Skip to content

Commit

Permalink
Changes based on PC version 0.2.
Browse files Browse the repository at this point in the history
  • Loading branch information
MaikelChan committed Jan 10, 2022
1 parent 85ad7b0 commit f5ef3ea
Show file tree
Hide file tree
Showing 10 changed files with 682 additions and 434 deletions.
120 changes: 120 additions & 0 deletions PlumbersDontWearTies/Audio.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#include "Audio.h"

#include "Log.h"

SDL_AudioDeviceID Audio::audioDeviceId = 0;
std::ifstream Audio::currentAudioStream = std::ifstream();
int32_t Audio::currentAudioStreamLegth = 0;

bool Audio::Initialize()
{
if (IsInitialized()) return false;

SDL_AudioSpec desiredAudioSpec, obtainedAudioSpec;
SDL_memset(&desiredAudioSpec, 0, sizeof(desiredAudioSpec));
desiredAudioSpec.freq = WAV_FREQUENCY;
desiredAudioSpec.format = WAV_FORMAT;
desiredAudioSpec.channels = WAV_CHANNELS;
desiredAudioSpec.samples = WAV_SAMPLES;
desiredAudioSpec.callback = AudioCallback;
audioDeviceId = SDL_OpenAudioDevice(NULL, 0, &desiredAudioSpec, &obtainedAudioSpec, /*SDL_AUDIO_ALLOW_FORMAT_CHANGE*/ 0);

if (audioDeviceId == 0)
{
Log::Print(LogTypes::Error, "Can't open audio device: %s", SDL_GetError());
return false;
}
else
{
Log::Print(LogTypes::Info, "Audio Initialized: frequency %i, channels %u, samples %u, buffer size %u.", obtainedAudioSpec.freq, obtainedAudioSpec.channels, obtainedAudioSpec.samples, obtainedAudioSpec.size);
}

SDL_PauseAudioDevice(audioDeviceId, 0);

return true;
}

void Audio::Dispose()
{
StopAudio();

if (audioDeviceId > 0)
{
SDL_CloseAudioDevice(audioDeviceId);
audioDeviceId = 0;
}
}

bool Audio::LoadAudioFromWAV(const std::string baseDataPath, const std::string fileName)
{
if (!IsInitialized()) return false;

StopAudio();

currentAudioStream = std::ifstream(baseDataPath + fileName, std::ios::binary);

if (!currentAudioStream.is_open())
{
Log::Print(LogTypes::Error, "Can't load audio file: %s", SDL_GetError());
return false;
}

currentAudioStream.seekg(0, std::ios_base::end);
currentAudioStreamLegth = static_cast<int32_t>(currentAudioStream.tellg());

// TODO: Does audio data in a WAV always start in the same offset?
currentAudioStream.seekg(WAV_DATA_START_POSITION, std::ios_base::beg);

Log::Print(LogTypes::Info, "Playing audio %s...", fileName.c_str());

return true;
}

void Audio::StopAudio()
{
if (!currentAudioStream.is_open()) return;

currentAudioStream.close();
currentAudioStream = std::ifstream();
currentAudioStreamLegth = 0;
}

void Audio::SetAudioPlaybackTime(const double elapsedTime)
{
if (!IsInitialized()) return;
if (!currentAudioStream.is_open()) return;

int32_t samplePosition = static_cast<int32_t>(elapsedTime * WAV_FREQUENCY * WAV_FORMAT_BYTES * WAV_CHANNELS);

// Make sure samplePosition is even, not odd, as audio is 16bit.
samplePosition &= ~1;

currentAudioStream.seekg(WAV_DATA_START_POSITION + samplePosition, std::ios_base::beg);
}

void Audio::AudioCallback(void* userdata, uint8_t* stream, int32_t len)
{
if (currentAudioStream.is_open())
{
currentAudioStream.read((char*)stream, len);

int32_t bytesRead = static_cast<int32_t>(currentAudioStream.gcount());
int32_t remainingBytes = len - bytesRead;

if (remainingBytes > 0)
{
SDL_memset(stream + bytesRead, 0, remainingBytes);

// We have finished reading the audio file,
// don't need to keep it open.

currentAudioStream.close();
currentAudioStream = std::ifstream();
currentAudioStreamLegth = 0;
}
}
else
{
SDL_memset(stream, 0, len);
}
}
38 changes: 38 additions & 0 deletions PlumbersDontWearTies/Audio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#pragma once

#include <fstream>

#include <SDL.h>

// Format of game's WAV files

constexpr int32_t WAV_FREQUENCY = 11025; // Hz
constexpr SDL_AudioFormat WAV_FORMAT = AUDIO_S16; // 16 bits
constexpr int32_t WAV_FORMAT_BYTES = 2; // 16 bits
constexpr int32_t WAV_CHANNELS = 2; // Stereo
constexpr int32_t WAV_SAMPLES = 256;

// TODO: Does audio data in a WAV always start in the same offset?

constexpr int32_t WAV_DATA_START_POSITION = 0x2c;

class Audio
{
private:
static SDL_AudioDeviceID audioDeviceId;
static std::ifstream currentAudioStream;
static int32_t currentAudioStreamLegth;

public:
static bool Initialize();
static void Dispose();

static bool LoadAudioFromWAV(const std::string baseDataPath, const std::string fileName);
static void StopAudio();
static void SetAudioPlaybackTime(const double elapsedTime);

inline static bool IsInitialized() { return audioDeviceId > 0; }

private:
static void AudioCallback(void* userdata, uint8_t* stream, int32_t len);
};
Loading

0 comments on commit f5ef3ea

Please sign in to comment.