aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/adlmidi.cpp80
-rw-r--r--src/adlmidi_private.hpp4
-rw-r--r--src/dbopl.cpp83
-rw-r--r--src/dbopl.h6
4 files changed, 104 insertions, 69 deletions
diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp
index 7f8564b..4710dfe 100644
--- a/src/adlmidi.cpp
+++ b/src/adlmidi.cpp
@@ -327,43 +327,6 @@ ADLMIDI_EXPORT void adl_positionRewind(struct ADL_MIDIPlayer *device)
}
-#ifdef ADLMIDI_USE_DOSBOX_OPL
-
-#define ADLMIDI_CLAMP(V, MIN, MAX) std::max(std::min(V, (MAX)), (MIN))
-
-inline static void SendStereoAudio(ADL_MIDIPlayer *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(ADL_MIDIPlayer *device,
int &samples_requested,
ssize_t &in_size,
@@ -379,18 +342,17 @@ inline static void SendStereoAudio(ADL_MIDIPlayer *device,
size_t inSamples = static_cast<size_t>(in_size * 2);
size_t maxSamples = static_cast<size_t>(samples_requested) - offset;
size_t toCopy = std::min(maxSamples, inSamples);
- memcpy(_out + out_pos, _in, toCopy * sizeof(short));
+ std::memcpy(_out + out_pos, _in, toCopy * sizeof(short));
if(maxSamples < inSamples)
{
size_t appendSize = inSamples - maxSamples;
- memcpy(device->backup_samples + device->backup_samples_size,
- maxSamples + _in, appendSize * sizeof(short));
+ std::memcpy(device->backup_samples + device->backup_samples_size,
+ maxSamples + _in, appendSize * sizeof(short));
device->backup_samples_size += (ssize_t)appendSize;
device->stored_samples += (ssize_t)appendSize;
}
}
-#endif
ADLMIDI_EXPORT int adl_play(ADL_MIDIPlayer *device, int sampleCount, short *out)
@@ -438,66 +400,52 @@ ADLMIDI_EXPORT int adl_play(ADL_MIDIPlayer *device, int sampleCount, short *out)
device->delay -= eat_delay;
device->carry += device->PCM_RATE * eat_delay;
n_periodCountStereo = static_cast<ssize_t>(device->carry);
- //n_periodCountPhys = n_periodCountStereo * 2;
device->carry -= n_periodCountStereo;
if(device->SkipForward > 0)
device->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 /*n_samples * 2*/);
MIDIplay *player = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
if((player->atEnd) && (device->delay <= 0.0))
break;//Stop to fetch samples at reaching of 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(device->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(device, sampleCount, in_generatedStereo, out_buf.data(), gotten_len, out);
+ SendStereoAudio(device, sampleCount, in_generatedStereo, out_buf, 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
- memset(out_buf.data(), 0, in_countStereoU * sizeof(short));
-
/* Generate data from every chip and mix result */
for(unsigned card = 0; card < device->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(device, sampleCount, in_generatedStereo, out_buf.data(), gotten_len, out);
+ SendStereoAudio(device, sampleCount, in_generatedStereo, out_buf, gotten_len, out);
}
left -= (int)in_generatedPhys;
diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp
index a6ea6ae..d3709a2 100644
--- a/src/adlmidi_private.hpp
+++ b/src/adlmidi_private.hpp
@@ -393,7 +393,7 @@ private:
{}
} CurrentPositionNew, LoopBeginPositionNew, trackBeginPositionNew;
- std::vector<std::vector<MidiTrackPos>> trackDataNew;
+ std::vector<std::vector<MidiTrackPos> > trackDataNew;
std::vector<int> trackDataNewStatus;
void buildTrackData();
MidiEvent parseEvent(uint8_t **ptr, int &status);
@@ -415,6 +415,8 @@ public:
loopStart_hit /*loopStart entry was hited in previous tick*/;
char ____padding2[2];
OPL3 opl;
+ //! Generated per-tick audio output buffer
+ int16_t outBuf[1024];
public:
static uint64_t ReadBEint(const void *buffer, size_t nbytes);
static uint64_t ReadLEint(const void *buffer, size_t nbytes);
diff --git a/src/dbopl.cpp b/src/dbopl.cpp
index 8bb3eb4..cd857f4 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,52 @@ 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) * size_t(*samples) * 2);
+ 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) * size_t(*samples) * 2);
+ if(!chip.opl3Active)
+ chip.GenerateBlock2_Mix(static_cast<Bitu>(*samples), out32);
+ else
+ chip.GenerateBlock3_Mix(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 bbe40de..d6091a2 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);
};