Skip to content

Commit

Permalink
Move AdjustVolume to AudioDecoderBase as this is needed for WildMidi.
Browse files Browse the repository at this point in the history
Also convert datatypes from double to float, is a bit faster and good enough here.
  • Loading branch information
Ghabry committed Aug 31, 2021
1 parent 67e5d8f commit 3ed688d
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 27 deletions.
18 changes: 4 additions & 14 deletions src/audio_decoder.cpp
Expand Up @@ -34,16 +34,6 @@

using namespace std::chrono_literals;

namespace {
static double AdjustVolume(double volume) {
// Adjust to RPG_RT (Direct Sound) volume scale
if (volume > 0) {
return 100 * std::pow(10, (-100 + volume) / 60.0);
}
return 0.0;
}
}

class WMAUnsupportedFormatDecoder : public AudioDecoder {
public:
WMAUnsupportedFormatDecoder() {
Expand Down Expand Up @@ -182,8 +172,8 @@ void AudioDecoder::Update(std::chrono::microseconds delta) {

fade_time -= delta;

volume += static_cast<double>(std::chrono::duration_cast<std::chrono::microseconds>(delta).count()) * delta_volume_step;
volume = Utils::Clamp<double>(static_cast<double>(volume), 0.0, 100.0);
volume += static_cast<float>(std::chrono::duration_cast<std::chrono::microseconds>(delta).count()) * delta_volume_step;
volume = Utils::Clamp(static_cast<float>(volume), 0.0f, 100.0f);
log_volume = AdjustVolume(volume);
}

Expand All @@ -192,7 +182,7 @@ int AudioDecoder::GetVolume() const {
}

void AudioDecoder::SetVolume(int new_volume) {
volume = Utils::Clamp<double>(static_cast<double>(new_volume), 0.0, 100.0);
volume = Utils::Clamp(static_cast<float>(new_volume), 0.0f, 100.0f);
log_volume = AdjustVolume(volume);
}

Expand All @@ -206,7 +196,7 @@ void AudioDecoder::SetFade(int end, std::chrono::milliseconds duration) {

fade_volume_end = end;
fade_time = duration;
delta_volume_step = (static_cast<double>(fade_volume_end) - volume) / fade_time.count();
delta_volume_step = (static_cast<float>(fade_volume_end) - volume) / fade_time.count();
}

int AudioDecoder::GetSamplesizeForFormat(AudioDecoderBase::Format format) {
Expand Down
6 changes: 3 additions & 3 deletions src/audio_decoder.h
Expand Up @@ -102,12 +102,12 @@ class AudioDecoder : public AudioDecoderBase {
void Update(std::chrono::microseconds delta) final override;
private:
bool paused = false;
double volume = 0.0;
double log_volume = 0.0; // as used by RPG_RT
float volume = 0.0f;
float log_volume = 0.0f; // as used by RPG_RT

int fade_volume_end = 0;
std::chrono::microseconds fade_time = std::chrono::microseconds(0);
double delta_volume_step = 0.0;
float delta_volume_step = 0.0f;
};

#endif
8 changes: 8 additions & 0 deletions src/audio_decoder_base.cpp
Expand Up @@ -23,6 +23,14 @@
#include "system.h"
#include "utils.h"

float AudioDecoderBase::AdjustVolume(float volume) {
// Adjust to RPG_RT (Direct Sound) volume scale
if (volume > 0) {
return 100.0f * std::pow<float>(10, (-100 + volume) / 60.0f);
}
return 0.0f;
}

int AudioDecoderBase::Decode(uint8_t* buffer, int length) {
return Decode(buffer, length, 0);
}
Expand Down
10 changes: 10 additions & 0 deletions src/audio_decoder_base.h
Expand Up @@ -35,6 +35,16 @@
*/
class AudioDecoderBase {
public:
/**
* Takes a linear volume and converts it to a logarithmic used by
* RPG_RT (Direct Sound).
* Do not use this for Midi, is already logarithmic by design.
*
* @param volume linear volume
* @return logarithmic volume
*/
static float AdjustVolume(float volume);

virtual ~AudioDecoderBase() = default;

/** Sample format */
Expand Down
18 changes: 11 additions & 7 deletions src/audio_decoder_midi.cpp
Expand Up @@ -148,13 +148,10 @@ void AudioDecoderMidi::Resume() {
}

int AudioDecoderMidi::GetVolume() const {
// When handled by Midi messages fake a 100 otherwise it is double-silenced
// When handled by Midi messages fake a 100 otherwise the volume is adjusted twice

if (!mididec->SupportsMidiMessages()) {
if (fade_steps > 0) {
return static_cast<int>(fade_volume_end * 100);
}
return 100;
return static_cast<int>(log_volume);
}

return 100;
Expand All @@ -164,11 +161,15 @@ void AudioDecoderMidi::SetVolume(int new_volume) {
// cancel any pending fades
fade_steps = 0;

volume = new_volume / 100.0f;
volume = static_cast<float>(new_volume) / 100.0f;
for (int i = 0; i < 16; i++) {
uint32_t msg = midimsg_volume(i, static_cast<uint8_t>(channel_volumes[i] * volume));
mididec->SendMidiMessage(msg);
}

if (!mididec->SupportsMidiMessages()) {
log_volume = AdjustVolume(volume * 100.0f);
}
}

void AudioDecoderMidi::SetFade(int end, std::chrono::milliseconds duration) {
Expand All @@ -181,7 +182,7 @@ void AudioDecoderMidi::SetFade(int end, std::chrono::milliseconds duration) {
}

fade_volume_end = end / 100.0f;
fade_steps = duration.count() / 100;
fade_steps = duration.count() / 100.0;
delta_volume_step = (fade_volume_end - volume) / fade_steps;
}

Expand Down Expand Up @@ -220,6 +221,9 @@ void AudioDecoderMidi::Update(std::chrono::microseconds delta) {
}
if (fade_steps >= 0 && mtime - last_fade_mtime > 0.1s) {
volume = Utils::Clamp<float>(volume + delta_volume_step, 0.0f, 1.0f);
if (!mididec->SupportsMidiMessages()) {
log_volume = AdjustVolume(volume * 100.0f);
}
for (int i = 0; i < 16; i++) {
uint32_t msg = midimsg_volume(i, static_cast<uint8_t>(channel_volumes[i] * volume));
mididec->SendMidiMessage(msg);
Expand Down
7 changes: 4 additions & 3 deletions src/audio_decoder_midi.h
Expand Up @@ -170,12 +170,13 @@ class AudioDecoderMidi final : public AudioDecoderBase, public midisequencer::ou
std::chrono::microseconds mtime = std::chrono::microseconds(0);
float pitch = 1.0f;
bool paused = false;
float volume = 0;
float volume = 0.0f;
float log_volume = 0.0f; // as used by RPG_RT, for Midi decoder without event support
bool loops_to_end = false;

int fade_steps = 0;
double fade_volume_end = 0;
double delta_volume_step = 0;
float fade_volume_end = 0;
float delta_volume_step = 0;
std::chrono::microseconds last_fade_mtime = std::chrono::microseconds(0);

int frequency = EP_MIDI_FREQ;
Expand Down

0 comments on commit 3ed688d

Please sign in to comment.