diff options
author | Wohlstand <admin@wohlnet.ru> | 2017-10-31 03:42:37 +0300 |
---|---|---|
committer | Wohlstand <admin@wohlnet.ru> | 2017-10-31 03:42:37 +0300 |
commit | 634fefa614f29056e5b4dadc1e4db9ce61d49e59 (patch) | |
tree | 1dfd49be726113898395449ae337308f138e43aa /src | |
parent | 78b48a4f7250f94b62a5c995f8c714804bb66eef (diff) | |
parent | 24f30e137009fda5262c6465742fb997a1ef8e8f (diff) | |
download | libADLMIDI-634fefa614f29056e5b4dadc1e4db9ce61d49e59.tar.gz libADLMIDI-634fefa614f29056e5b4dadc1e4db9ce61d49e59.tar.bz2 libADLMIDI-634fefa614f29056e5b4dadc1e4db9ce61d49e59.zip |
Merge branch 'master' into seekability
# Conflicts:
# libADLMIDI-test.pro
# src/adlmidi.cpp
# src/adlmidi_private.hpp
Diffstat (limited to 'src')
-rw-r--r-- | src/adlmidi.cpp | 79 | ||||
-rw-r--r-- | src/adlmidi_private.hpp | 2 | ||||
-rw-r--r-- | src/dbopl.cpp | 82 | ||||
-rw-r--r-- | src/dbopl.h | 6 |
4 files changed, 99 insertions, 70 deletions
diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp index a7bab22..7aa9e8b 100644 --- a/src/adlmidi.cpp +++ b/src/adlmidi.cpp @@ -346,43 +346,6 @@ ADLMIDI_EXPORT void adl_setTempo(struct ADL_MIDIPlayer *device, double tempo) } -#ifdef ADLMIDI_USE_DOSBOX_OPL - -#define ADLMIDI_CLAMP(V, MIN, MAX) std::max(std::min(V, (MAX)), (MIN)) - -inline static void SendStereoAudio(MIDIplay::Setup &device, - int &samples_requested, - ssize_t &in_size, - int *_in, - ssize_t out_pos, - short *_out) -{ - if(!in_size) return; - - device.stored_samples = 0; - ssize_t out; - ssize_t offset; - ssize_t pos = static_cast<ssize_t>(out_pos); - - for(ssize_t p = 0; p < in_size; ++p) - { - for(ssize_t w = 0; w < 2; ++w) - { - out = _in[p * 2 + w]; - offset = pos + p * 2 + w; - - if(offset < samples_requested) - _out[offset] = static_cast<short>(ADLMIDI_CLAMP(out, static_cast<ssize_t>(INT16_MIN), static_cast<ssize_t>(INT16_MAX))); - else - { - device.backup_samples[device.backup_samples_size] = static_cast<short>(out); - device.backup_samples_size++; - device.stored_samples++; - } - } - } -} -#else inline static void SendStereoAudio(MIDIplay::Setup &device, int &samples_requested, ssize_t &in_size, @@ -409,7 +372,6 @@ inline static void SendStereoAudio(MIDIplay::Setup &device, device.stored_samples += (ssize_t)appendSize; } } -#endif ADLMIDI_EXPORT int adl_play(ADL_MIDIPlayer *device, int sampleCount, short *out) @@ -460,70 +422,51 @@ ADLMIDI_EXPORT int adl_play(ADL_MIDIPlayer *device, int sampleCount, short *out) setup.delay -= eat_delay; setup.carry += setup.PCM_RATE * eat_delay; n_periodCountStereo = static_cast<ssize_t>(setup.carry); - //n_periodCountPhys = n_periodCountStereo * 2; setup.carry -= n_periodCountStereo; if(setup.SkipForward > 0) setup.SkipForward -= 1; else { - #ifdef ADLMIDI_USE_DOSBOX_OPL - std::vector<int> out_buf; - #else - std::vector<int16_t> out_buf; - #endif - out_buf.resize(1024, 0); - if((player->atEnd) && (setup.delay <= 0.0)) break;//Stop to fetch samples at reaching the song end with disabled loop + //! Count of stereo samples ssize_t in_generatedStereo = (n_periodCountStereo > 512) ? 512 : n_periodCountStereo; + //! Total count of samples ssize_t in_generatedPhys = in_generatedStereo * 2; - + //! Unsigned total sample count //fill buffer with zeros - size_t in_countStereoU = static_cast<size_t>(in_generatedStereo * 2); + int16_t *out_buf = player->outBuf; + std::memset(out_buf, 0, static_cast<size_t>(in_generatedPhys) * sizeof(int16_t)); if(player->m_setup.NumCards == 1) { #ifdef ADLMIDI_USE_DOSBOX_OPL - player->opl.cards[0].GenerateArr(out_buf.data(), &in_generatedStereo); + player->opl.cards[0].GenerateArr(out_buf, &in_generatedStereo); in_generatedPhys = in_generatedStereo * 2; #else - OPL3_GenerateStream(&player->opl.cards[0], out_buf.data(), static_cast<Bit32u>(in_generatedStereo)); + OPL3_GenerateStream(&player->opl.cards[0], out_buf, static_cast<Bit32u>(in_generatedStereo)); #endif - /* Process it */ - SendStereoAudio(setup, sampleCount, in_generatedStereo, out_buf.data(), gotten_len, out); } else if(n_periodCountStereo > 0) { - #ifdef ADLMIDI_USE_DOSBOX_OPL - std::vector<int32_t> in_mixBuffer; - in_mixBuffer.resize(1024); //n_samples * 2 - ssize_t in_generatedStereo = n_periodCountStereo; - #endif - std::memset(out_buf.data(), 0, in_countStereoU * sizeof(short)); - /* Generate data from every chip and mix result */ for(unsigned card = 0; card < player->m_setup.NumCards; ++card) { #ifdef ADLMIDI_USE_DOSBOX_OPL - player->opl.cards[card].GenerateArr(in_mixBuffer.data(), &in_generatedStereo); + player->opl.cards[card].GenerateArrMix(out_buf, &in_generatedStereo); in_generatedPhys = in_generatedStereo * 2; - size_t in_samplesCount = static_cast<size_t>(in_generatedPhys); - for(size_t a = 0; a < in_samplesCount; ++a) - out_buf[a] += in_mixBuffer[a]; #else - OPL3_GenerateStreamMix(&player->opl.cards[card], out_buf.data(), static_cast<Bit32u>(in_generatedStereo)); + OPL3_GenerateStreamMix(&player->opl.cards[card], out_buf, static_cast<Bit32u>(in_generatedStereo)); #endif } - - /* Process it */ - SendStereoAudio(setup, sampleCount, in_generatedStereo, out_buf.data(), gotten_len, out); } + /* Process it */ + SendStereoAudio(setup, sampleCount, in_generatedStereo, out_buf, gotten_len, out); left -= (int)in_generatedPhys; gotten_len += (in_generatedPhys) - setup.stored_samples; - out_buf.clear(); } setup.delay = player->Tick(eat_delay, setup.mindelay); diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp index a2ec8c1..622e9f2 100644 --- a/src/adlmidi_private.hpp +++ b/src/adlmidi_private.hpp @@ -479,6 +479,8 @@ public: char ____padding2[2]; OPL3 opl; + int16_t outBuf[1024]; + struct Setup { unsigned int AdlBank; diff --git a/src/dbopl.cpp b/src/dbopl.cpp index 8bb3eb4..fb28e20 100644 --- a/src/dbopl.cpp +++ b/src/dbopl.cpp @@ -45,6 +45,10 @@ typedef struct vswprintf {} swprintf; #include <string.h> #include "dbopl.h" +#define DB_MAX(x, y) ((x) > (y) ? (x) : (y)) +#define DB_MIN(x, y) ((x) < (y) ? (x) : (y)) + +#define DBOPL_CLAMP(V, MIN, MAX) DB_MAX(DB_MIN(V, (MAX)), (MIN)) #ifndef PI #define PI 3.14159265358979323846 @@ -1482,7 +1486,7 @@ namespace DBOPL { while(total > 0) { - Bit32u samples = ForwardLFO(total); + Bit32u samples = ForwardLFO((Bit32u)total); memset(output, 0, sizeof(Bit32s) * samples * 2); int count = 0; @@ -1497,6 +1501,39 @@ namespace DBOPL } } + void Chip::GenerateBlock2_Mix(Bitu total, Bit32s *output) + { + while(total > 0) + { + Bit32u samples = ForwardLFO((Bit32u)total); + int count = 0; + for(Channel *ch = chan; ch < chan + 9;) + { + count++; + ch = (ch->*(ch->synthHandler))(this, samples, output); + } + + total -= samples; + output += samples; + } + } + + void Chip::GenerateBlock3_Mix(Bitu total, Bit32s *output) + { + while(total > 0) + { + Bit32u samples = ForwardLFO(total); + int count = 0; + for(Channel *ch = chan; ch < chan + 18;) + { + count++; + ch = (ch->*(ch->synthHandler))(this, samples, output); + } + total -= samples; + output += samples * 2; + } + } + void Chip::Setup(Bit32u rate) { double original = OPLRATE; @@ -1955,10 +1992,51 @@ namespace DBOPL chip.GenerateBlock3(static_cast<Bitu>(*samples), out); } + void Handler::GenerateArr(Bit16s *out, ssize_t *samples) + { + Bit32s out32[1024]; + if(GCC_UNLIKELY(*samples > 512)) + *samples = 512; + memset(out32, 0, sizeof(Bit32s) * 1024); + if(!chip.opl3Active) + chip.GenerateBlock2(static_cast<Bitu>(*samples), out32); + else + chip.GenerateBlock3(static_cast<Bitu>(*samples), out32); + ssize_t sz = *samples * 2; + for(ssize_t i = 0; i < sz; i++) + out[i] = static_cast<Bit16s>(DBOPL_CLAMP(out32[i], static_cast<ssize_t>(INT16_MIN), static_cast<ssize_t>(INT16_MAX))); + } + + void Handler::GenerateArrMix(Bit32s *out, ssize_t *samples) + { + if(GCC_UNLIKELY(*samples > 512)) + *samples = 512; + if(!chip.opl3Active) + chip.GenerateBlock2_Mix(static_cast<Bitu>(*samples), out); + else + chip.GenerateBlock3_Mix(static_cast<Bitu>(*samples), out); + } + + void Handler::GenerateArrMix(Bit16s *out, ssize_t *samples) + { + Bit32s out32[1024]; + if(GCC_UNLIKELY(*samples > 512)) + *samples = 512; + memset(out32, 0, sizeof(Bit32s) * 1024); + if(!chip.opl3Active) + chip.GenerateBlock2(static_cast<Bitu>(*samples), out32); + else + chip.GenerateBlock3(static_cast<Bitu>(*samples), out32); + ssize_t sz = *samples * 2; + for(ssize_t i = 0; i < sz; i++) + out[i] += static_cast<Bit16s>(DBOPL_CLAMP(out32[i], static_cast<ssize_t>(INT16_MIN), static_cast<ssize_t>(INT16_MAX))); + } + + void Handler::Init(Bitu rate) { InitTables(); - chip.Setup(rate); + chip.Setup((Bit32u)rate); } diff --git a/src/dbopl.h b/src/dbopl.h index 54384da..826cb44 100644 --- a/src/dbopl.h +++ b/src/dbopl.h @@ -277,6 +277,9 @@ namespace DBOPL void GenerateBlock2(Bitu samples, Bit32s *output); void GenerateBlock3(Bitu samples, Bit32s *output); + void GenerateBlock2_Mix(Bitu samples, Bit32s *output); + void GenerateBlock3_Mix(Bitu samples, Bit32s *output); + void Generate(Bit32u samples); void Setup(Bit32u r); @@ -293,6 +296,9 @@ namespace DBOPL Bitu samples); void GenerateArr(Bit32s *out, Bitu *samples); void GenerateArr(Bit32s *out, ssize_t *samples); + void GenerateArr(Bit16s *out, ssize_t *samples); + void GenerateArrMix(Bit32s *out, ssize_t *samples); + void GenerateArrMix(Bit16s *out, ssize_t *samples); void Init(Bitu rate); }; |