aboutsummaryrefslogtreecommitdiff
path: root/src/adlmidi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/adlmidi.cpp')
-rw-r--r--src/adlmidi.cpp245
1 files changed, 131 insertions, 114 deletions
diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp
index 4710dfe..7aa9e8b 100644
--- a/src/adlmidi.cpp
+++ b/src/adlmidi.cpp
@@ -31,36 +31,11 @@ ADLMIDI_EXPORT struct ADL_MIDIPlayer *adl_init(long sample_rate)
{
ADL_MIDIPlayer *midi_device;
midi_device = (ADL_MIDIPlayer *)malloc(sizeof(ADL_MIDIPlayer));
- midi_device->PCM_RATE = static_cast<unsigned long>(sample_rate);
- midi_device->AdlBank = 0;
- midi_device->NumFourOps = 7;
- midi_device->NumCards = 2;
- midi_device->HighTremoloMode = 0;
- midi_device->HighVibratoMode = 0;
- midi_device->AdlPercussionMode = 0;
- midi_device->LogarithmicVolumes = 0;
- midi_device->SkipForward = 0;
- midi_device->loopingIsEnabled = 0;
- midi_device->ScaleModulators = 0;
- midi_device->delay = 0.0;
- midi_device->carry = 0.0;
- midi_device->mindelay = 1.0 / (double)midi_device->PCM_RATE;
- midi_device->maxdelay = 512.0 / (double)midi_device->PCM_RATE;
- midi_device->stored_samples = 0;
- midi_device->backup_samples_size = 0;
-
MIDIplay *player = new MIDIplay;
midi_device->adl_midiPlayer = player;
- player->config = midi_device;
- player->opl._parent = midi_device;
- player->opl.NumCards = midi_device->NumCards;
- player->opl.AdlBank = midi_device->AdlBank;
- player->opl.NumFourOps = midi_device->NumFourOps;
- player->opl.LogarithmicVolumes = (midi_device->LogarithmicVolumes != 0);
- player->opl.HighTremoloMode = (midi_device->HighTremoloMode != 0);
- player->opl.HighVibratoMode = (midi_device->HighVibratoMode != 0);
- player->opl.AdlPercussionMode = (midi_device->AdlPercussionMode != 0);
- player->opl.ScaleModulators = (midi_device->ScaleModulators != 0);
+ player->m_setup.PCM_RATE = static_cast<unsigned long>(sample_rate);
+ player->m_setup.mindelay = 1.0 / (double)player->m_setup.PCM_RATE;
+ player->m_setup.maxdelay = 512.0 / (double)player->m_setup.PCM_RATE;
player->ChooseDevice("none");
adlRefreshNumCards(midi_device);
return midi_device;
@@ -71,10 +46,9 @@ ADLMIDI_EXPORT int adl_setNumCards(ADL_MIDIPlayer *device, int numCards)
if(device == NULL)
return -2;
- device->NumCards = static_cast<unsigned int>(numCards);
- reinterpret_cast<MIDIplay *>(device->adl_midiPlayer)->opl.NumCards = device->NumCards;
-
- if(device->NumCards < 1 || device->NumCards > MaxCards)
+ MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ play->m_setup.NumCards = static_cast<unsigned int>(numCards);
+ if(play->m_setup.NumCards < 1 || play->m_setup.NumCards > MaxCards)
{
std::stringstream s;
s << "number of cards may only be 1.." << MaxCards << ".\n";
@@ -82,6 +56,8 @@ ADLMIDI_EXPORT int adl_setNumCards(ADL_MIDIPlayer *device, int numCards)
return -1;
}
+ play->opl.NumCards = play->m_setup.NumCards;
+
return adlRefreshNumCards(device);
}
@@ -99,11 +75,11 @@ ADLMIDI_EXPORT int adl_setBank(ADL_MIDIPlayer *device, int bank)
if(bankno < 0)
bankno = 0;
- device->AdlBank = static_cast<uint32_t>(bankno);
MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
- play->opl.AdlBank = device->AdlBank;
+ play->m_setup.AdlBank = static_cast<uint32_t>(bankno);
+ play->opl.AdlBank = play->m_setup.AdlBank;
- if(device->AdlBank >= NumBanks)
+ if(play->m_setup.AdlBank >= NumBanks)
{
std::stringstream s;
s << "bank number may only be 0.." << (NumBanks - 1) << ".\n";
@@ -127,13 +103,16 @@ ADLMIDI_EXPORT const char *const *adl_getBankNames()
ADLMIDI_EXPORT int adl_setNumFourOpsChn(ADL_MIDIPlayer *device, int ops4)
{
- device->NumFourOps = static_cast<unsigned int>(ops4);
- reinterpret_cast<MIDIplay *>(device->adl_midiPlayer)->opl.NumFourOps = device->NumFourOps;
+ if(!device)
+ return -1;
+ MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ play->m_setup.NumFourOps = static_cast<unsigned int>(ops4);
+ play->opl.NumFourOps = play->m_setup.NumFourOps;
- if(device->NumFourOps > 6 * device->NumCards)
+ if(play->m_setup.NumFourOps > 6 * play->m_setup.NumCards)
{
std::stringstream s;
- s << "number of four-op channels may only be 0.." << (6 * (device->NumCards)) << " when " << device->NumCards << " OPL3 cards are used.\n";
+ s << "number of four-op channels may only be 0.." << (6 * (play->m_setup.NumCards)) << " when " << play->m_setup.NumCards << " OPL3 cards are used.\n";
ADLMIDI_ErrorString = s.str();
return -1;
}
@@ -145,55 +124,56 @@ ADLMIDI_EXPORT int adl_setNumFourOpsChn(ADL_MIDIPlayer *device, int ops4)
ADLMIDI_EXPORT void adl_setPercMode(ADL_MIDIPlayer *device, int percmod)
{
if(!device) return;
-
- device->AdlPercussionMode = static_cast<unsigned int>(percmod);
- reinterpret_cast<MIDIplay *>(device->adl_midiPlayer)->opl.AdlPercussionMode = (device->AdlPercussionMode != 0);
+ MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ play->m_setup.AdlPercussionMode = (percmod != 0);
+ play->opl.AdlPercussionMode = play->m_setup.AdlPercussionMode;
}
ADLMIDI_EXPORT void adl_setHVibrato(ADL_MIDIPlayer *device, int hvibro)
{
if(!device) return;
-
- device->HighVibratoMode = static_cast<unsigned int>(hvibro);
- reinterpret_cast<MIDIplay *>(device->adl_midiPlayer)->opl.HighVibratoMode = (device->HighVibratoMode != 0);
+ MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ play->m_setup.HighVibratoMode = (hvibro != 0);
+ play->opl.HighVibratoMode = play->m_setup.HighVibratoMode;
}
ADLMIDI_EXPORT void adl_setHTremolo(ADL_MIDIPlayer *device, int htremo)
{
if(!device) return;
-
- device->HighTremoloMode = static_cast<unsigned int>(htremo);
- reinterpret_cast<MIDIplay *>(device->adl_midiPlayer)->opl.HighTremoloMode = (device->HighTremoloMode != 0);
+ MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ play->m_setup.HighTremoloMode = (htremo != 0);
+ play->opl.HighTremoloMode = play->m_setup.HighTremoloMode;
}
ADLMIDI_EXPORT void adl_setScaleModulators(ADL_MIDIPlayer *device, int smod)
{
if(!device) return;
-
- device->ScaleModulators = static_cast<unsigned int>(smod);
- reinterpret_cast<MIDIplay *>(device->adl_midiPlayer)->opl.ScaleModulators = (device->ScaleModulators != 0);
+ MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ play->m_setup.ScaleModulators = (smod != 0);
+ play->opl.ScaleModulators = play->m_setup.ScaleModulators;
}
ADLMIDI_EXPORT void adl_setLoopEnabled(ADL_MIDIPlayer *device, int loopEn)
{
if(!device) return;
- device->loopingIsEnabled = (loopEn != 0);
+ MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ play->m_setup.loopingIsEnabled = (loopEn != 0);
}
ADLMIDI_EXPORT void adl_setLogarithmicVolumes(struct ADL_MIDIPlayer *device, int logvol)
{
if(!device) return;
-
- device->LogarithmicVolumes = static_cast<unsigned int>(logvol);
- reinterpret_cast<MIDIplay *>(device->adl_midiPlayer)->opl.LogarithmicVolumes = (device->LogarithmicVolumes != 0);
+ MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ play->m_setup.LogarithmicVolumes = (logvol != 0);
+ play->opl.LogarithmicVolumes = play->m_setup.LogarithmicVolumes;
}
ADLMIDI_EXPORT void adl_setVolumeRangeModel(struct ADL_MIDIPlayer *device, int volumeModel)
{
if(!device) return;
-
- device->VolumeModel = volumeModel;
- reinterpret_cast<MIDIplay *>(device->adl_midiPlayer)->opl.ChangeVolumeRangesModel(static_cast<ADLMIDI_VolumeModels>(volumeModel));
+ MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ play->m_setup.VolumeModel = volumeModel;
+ play->opl.ChangeVolumeRangesModel(static_cast<ADLMIDI_VolumeModels>(volumeModel));
}
ADLMIDI_EXPORT int adl_openBankFile(struct ADL_MIDIPlayer *device, char *filePath)
@@ -202,10 +182,10 @@ ADLMIDI_EXPORT int adl_openBankFile(struct ADL_MIDIPlayer *device, char *filePat
if(device && device->adl_midiPlayer)
{
- device->stored_samples = 0;
- device->backup_samples_size = 0;
-
- if(!reinterpret_cast<MIDIplay *>(device->adl_midiPlayer)->LoadBank(filePath))
+ MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ play->m_setup.stored_samples = 0;
+ play->m_setup.backup_samples_size = 0;
+ if(!play->LoadBank(filePath))
{
if(ADLMIDI_ErrorString.empty())
ADLMIDI_ErrorString = "ADL MIDI: Can't load file";
@@ -224,10 +204,10 @@ ADLMIDI_EXPORT int adl_openBankData(struct ADL_MIDIPlayer *device, void *mem, lo
if(device && device->adl_midiPlayer)
{
- device->stored_samples = 0;
- device->backup_samples_size = 0;
-
- if(!reinterpret_cast<MIDIplay *>(device->adl_midiPlayer)->LoadBank(mem, static_cast<size_t>(size)))
+ MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ play->m_setup.stored_samples = 0;
+ play->m_setup.backup_samples_size = 0;
+ if(!play->LoadBank(mem, static_cast<size_t>(size)))
{
if(ADLMIDI_ErrorString.empty())
ADLMIDI_ErrorString = "ADL MIDI: Can't load data from memory";
@@ -246,14 +226,13 @@ ADLMIDI_EXPORT int adl_openFile(ADL_MIDIPlayer *device, char *filePath)
if(device && device->adl_midiPlayer)
{
- device->stored_samples = 0;
- device->backup_samples_size = 0;
-
- if(!reinterpret_cast<MIDIplay *>(device->adl_midiPlayer)->LoadMIDI(filePath))
+ MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ play->m_setup.stored_samples = 0;
+ play->m_setup.backup_samples_size = 0;
+ if(!play->LoadMIDI(filePath))
{
if(ADLMIDI_ErrorString.empty())
ADLMIDI_ErrorString = "ADL MIDI: Can't load file";
-
return -1;
}
else return 0;
@@ -269,14 +248,13 @@ ADLMIDI_EXPORT int adl_openData(ADL_MIDIPlayer *device, void *mem, long size)
if(device && device->adl_midiPlayer)
{
- device->stored_samples = 0;
- device->backup_samples_size = 0;
-
- if(!reinterpret_cast<MIDIplay *>(device->adl_midiPlayer)->LoadMIDI(mem, static_cast<size_t>(size)))
+ MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ play->m_setup.stored_samples = 0;
+ play->m_setup.backup_samples_size = 0;
+ if(!play->LoadMIDI(mem, static_cast<size_t>(size)))
{
if(ADLMIDI_ErrorString.empty())
ADLMIDI_ErrorString = "ADL MIDI: Can't load data from memory";
-
return -1;
}
else return 0;
@@ -294,8 +272,8 @@ ADLMIDI_EXPORT const char *adl_errorString()
ADLMIDI_EXPORT const char *adl_getMusicTitle(ADL_MIDIPlayer *device)
{
- if(!device) return "";
-
+ if(!device)
+ return "";
return reinterpret_cast<MIDIplay *>(device->adl_midiPlayer)->musTitle.c_str();
}
@@ -303,7 +281,6 @@ ADLMIDI_EXPORT void adl_close(ADL_MIDIPlayer *device)
{
if(device->adl_midiPlayer)
delete reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
-
device->adl_midiPlayer = NULL;
free(device);
device = NULL;
@@ -313,10 +290,45 @@ ADLMIDI_EXPORT void adl_reset(ADL_MIDIPlayer *device)
{
if(!device)
return;
+ MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ play->m_setup.stored_samples = 0;
+ play->m_setup.backup_samples_size = 0;
+ play->opl.Reset(play->m_setup.PCM_RATE);
+}
+
+ADLMIDI_EXPORT double adl_totalTimeLength(ADL_MIDIPlayer *device)
+{
+ if(!device)
+ return -1.0;
+ return reinterpret_cast<MIDIplay *>(device->adl_midiPlayer)->timeLength();
+}
+
+ADLMIDI_EXPORT double adl_loopStartTime(struct ADL_MIDIPlayer *device)
+{
+ if(!device)
+ return -1.0;
+ return reinterpret_cast<MIDIplay *>(device->adl_midiPlayer)->getLoopStart();
+}
+
+ADLMIDI_EXPORT double adl_loopEndTime(struct ADL_MIDIPlayer *device)
+{
+ if(!device)
+ return -1.0;
+ return reinterpret_cast<MIDIplay *>(device->adl_midiPlayer)->getLoopEnd();
+}
- device->stored_samples = 0;
- device->backup_samples_size = 0;
- reinterpret_cast<MIDIplay *>(device->adl_midiPlayer)->opl.Reset();
+ADLMIDI_EXPORT double adl_positionTell(struct ADL_MIDIPlayer *device)
+{
+ if(!device)
+ return -1.0;
+ return reinterpret_cast<MIDIplay *>(device->adl_midiPlayer)->tell();
+}
+
+ADLMIDI_EXPORT void adl_positionSeek(struct ADL_MIDIPlayer *device, double seconds)
+{
+ if(!device)
+ return;
+ reinterpret_cast<MIDIplay *>(device->adl_midiPlayer)->seek(seconds);
}
ADLMIDI_EXPORT void adl_positionRewind(struct ADL_MIDIPlayer *device)
@@ -326,8 +338,15 @@ ADLMIDI_EXPORT void adl_positionRewind(struct ADL_MIDIPlayer *device)
reinterpret_cast<MIDIplay *>(device->adl_midiPlayer)->rewind();
}
+ADLMIDI_EXPORT void adl_setTempo(struct ADL_MIDIPlayer *device, double tempo)
+{
+ if(!device || (tempo <= 0.0))
+ return;
+ reinterpret_cast<MIDIplay *>(device->adl_midiPlayer)->setTempo(tempo);
+}
+
-inline static void SendStereoAudio(ADL_MIDIPlayer *device,
+inline static void SendStereoAudio(MIDIplay::Setup &device,
int &samples_requested,
ssize_t &in_size,
short *_in,
@@ -337,7 +356,7 @@ inline static void SendStereoAudio(ADL_MIDIPlayer *device,
if(!in_size)
return;
- device->stored_samples = 0;
+ device.stored_samples = 0;
size_t offset = static_cast<size_t>(out_pos);
size_t inSamples = static_cast<size_t>(in_size * 2);
size_t maxSamples = static_cast<size_t>(samples_requested) - offset;
@@ -347,10 +366,10 @@ inline static void SendStereoAudio(ADL_MIDIPlayer *device,
if(maxSamples < inSamples)
{
size_t appendSize = inSamples - maxSamples;
- std::memcpy(device->backup_samples + device->backup_samples_size,
+ 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;
+ device.backup_samples_size += (ssize_t)appendSize;
+ device.stored_samples += (ssize_t)appendSize;
}
}
@@ -360,6 +379,9 @@ ADLMIDI_EXPORT int adl_play(ADL_MIDIPlayer *device, int sampleCount, short *out)
if(!device)
return 0;
+ MIDIplay *player = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ MIDIplay::Setup &setup = player->m_setup;
+
sampleCount -= sampleCount % 2; //Avoid even sample requests
if(sampleCount < 0)
@@ -372,44 +394,42 @@ ADLMIDI_EXPORT int adl_play(ADL_MIDIPlayer *device, int sampleCount, short *out)
while(left > 0)
{
- if(device->backup_samples_size > 0)
+ if(setup.backup_samples_size > 0)
{
//Send reserved samples if exist
ssize_t ate = 0;
- while((ate < device->backup_samples_size) && (ate < left))
+ while((ate < setup.backup_samples_size) && (ate < left))
{
- out[ate] = device->backup_samples[ate];
+ out[ate] = setup.backup_samples[ate];
ate++;
}
left -= (int)ate;
gotten_len += ate;
- if(ate < device->backup_samples_size)
+ if(ate < setup.backup_samples_size)
{
for(ssize_t j = 0; j < ate; j++)
- device->backup_samples[(ate - 1) - j] = device->backup_samples[(device->backup_samples_size - 1) - j];
+ setup.backup_samples[(ate - 1) - j] = setup.backup_samples[(setup.backup_samples_size - 1) - j];
}
- device->backup_samples_size -= ate;
+ setup.backup_samples_size -= ate;
}
else
{
- const double eat_delay = device->delay < device->maxdelay ? device->delay : device->maxdelay;
- device->delay -= eat_delay;
- device->carry += device->PCM_RATE * eat_delay;
- n_periodCountStereo = static_cast<ssize_t>(device->carry);
- device->carry -= n_periodCountStereo;
-
- if(device->SkipForward > 0)
- device->SkipForward -= 1;
+ const double eat_delay = setup.delay < setup.maxdelay ? setup.delay : setup.maxdelay;
+ setup.delay -= eat_delay;
+ setup.carry += setup.PCM_RATE * eat_delay;
+ n_periodCountStereo = static_cast<ssize_t>(setup.carry);
+ setup.carry -= n_periodCountStereo;
+
+ if(setup.SkipForward > 0)
+ setup.SkipForward -= 1;
else
{
- 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
+ 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;
@@ -420,7 +440,7 @@ ADLMIDI_EXPORT int adl_play(ADL_MIDIPlayer *device, int sampleCount, short *out)
int16_t *out_buf = player->outBuf;
std::memset(out_buf, 0, static_cast<size_t>(in_generatedPhys) * sizeof(int16_t));
- if(device->NumCards == 1)
+ if(player->m_setup.NumCards == 1)
{
#ifdef ADLMIDI_USE_DOSBOX_OPL
player->opl.cards[0].GenerateArr(out_buf, &in_generatedStereo);
@@ -428,13 +448,11 @@ ADLMIDI_EXPORT int adl_play(ADL_MIDIPlayer *device, int sampleCount, short *out)
#else
OPL3_GenerateStream(&player->opl.cards[0], out_buf, static_cast<Bit32u>(in_generatedStereo));
#endif
- /* Process it */
- SendStereoAudio(device, sampleCount, in_generatedStereo, out_buf, gotten_len, out);
}
else if(n_periodCountStereo > 0)
{
/* Generate data from every chip and mix result */
- for(unsigned card = 0; card < device->NumCards; ++card)
+ for(unsigned card = 0; card < player->m_setup.NumCards; ++card)
{
#ifdef ADLMIDI_USE_DOSBOX_OPL
player->opl.cards[card].GenerateArrMix(out_buf, &in_generatedStereo);
@@ -443,16 +461,15 @@ ADLMIDI_EXPORT int adl_play(ADL_MIDIPlayer *device, int sampleCount, short *out)
OPL3_GenerateStreamMix(&player->opl.cards[card], out_buf, static_cast<Bit32u>(in_generatedStereo));
#endif
}
-
- /* Process it */
- SendStereoAudio(device, sampleCount, in_generatedStereo, out_buf, gotten_len, out);
}
+ /* Process it */
+ SendStereoAudio(setup, sampleCount, in_generatedStereo, out_buf, gotten_len, out);
left -= (int)in_generatedPhys;
- gotten_len += (in_generatedPhys) - device->stored_samples;
+ gotten_len += (in_generatedPhys) - setup.stored_samples;
}
- device->delay = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer)->Tick(eat_delay, device->mindelay);
+ setup.delay = player->Tick(eat_delay, setup.mindelay);
}
}