示例#1
0
ADLMIDI_EXPORT int adl_loadEmbeddedBank(struct ADL_MIDIPlayer *device, ADL_Bank *bank, int num)
{
    if(!device)
        return -1;

#ifdef DISABLE_EMBEDDED_BANKS
    ADL_UNUSED(bank);
    ADL_UNUSED(num);
    MidiPlayer *play = GET_MIDI_PLAYER(device);
    assert(play);
    play->setErrorString("This build of libADLMIDI has no embedded banks. "
                         "Please load banks by using adl_openBankFile() or "
                         "adl_openBankData() functions instead of adl_loadEmbeddedBank().");
    return -1;
#else
    if(num < 0 || num >= maxAdlBanks())
        return -1;

    OPL3::BankMap::iterator it = OPL3::BankMap::iterator::from_ptrs(bank->pointer);
    size_t id = it->first;

    for (unsigned i = 0; i < 128; ++i) {
        size_t insno = i + ((id & OPL3::PercussionTag) ? 128 : 0);
        size_t adlmeta = ::banks[num][insno];
        it->second.ins[i] = adlinsdata2::from_adldata(::adlins[adlmeta]);
    }
    return 0;
#endif
}
示例#2
0
ADLMIDI_EXPORT int adl_openData(ADL_MIDIPlayer *device, const void *mem, unsigned long size)
{
    if(device)
    {
        MidiPlayer *play = GET_MIDI_PLAYER(device);
        assert(play);
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
        play->m_setup.tick_skip_samples_delay = 0;
        if(!play->LoadMIDI(mem, static_cast<size_t>(size)))
        {
            std::string err = play->getErrorString();
            if(err.empty())
                play->setErrorString("ADL MIDI: Can't load data from memory");
            return -1;
        }
        else return 0;
#else
        ADL_UNUSED(mem);
        ADL_UNUSED(size);
        play->setErrorString("ADLMIDI: MIDI Sequencer is not supported in this build of library!");
        return -1;
#endif //ADLMIDI_DISABLE_MIDI_SEQUENCER
    }
    ADLMIDI_ErrorString = "Can't load file: ADL MIDI is not initialized";
    return -1;
}
示例#3
0
ADLMIDI_EXPORT void adl_setTempo(struct ADL_MIDIPlayer *device, double tempo)
{
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
    if(!device || (tempo <= 0.0))
        return;
    MidiPlayer *play = GET_MIDI_PLAYER(device);
    assert(play);
    play->m_sequencer.setTempo(tempo);
#else
    ADL_UNUSED(device);
    ADL_UNUSED(tempo);
#endif
}
示例#4
0
ADLMIDI_EXPORT double adl_tickEvents(struct ADL_MIDIPlayer *device, double seconds, double granulality)
{
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
    if(!device)
        return -1.0;
    MidiPlayer *play = GET_MIDI_PLAYER(device);
    assert(play);
    return play->Tick(seconds, granulality);
#else
    ADL_UNUSED(device);
    ADL_UNUSED(seconds);
    ADL_UNUSED(granulality);
    return -1.0;
#endif
}
示例#5
0
ADLMIDI_EXPORT void adl_setRawEventHook(struct ADL_MIDIPlayer *device, ADL_RawEventHook rawEventHook, void *userData)
{
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
    if(!device)
        return;
    MidiPlayer *play = GET_MIDI_PLAYER(device);
    assert(play);
    play->m_sequencerInterface.onEvent = rawEventHook;
    play->m_sequencerInterface.onEvent_userData = userData;
#else
    ADL_UNUSED(device);
    ADL_UNUSED(rawEventHook);
    ADL_UNUSED(userData);
#endif
}
示例#6
0
ADLMIDI_EXPORT int adl_setBank(ADL_MIDIPlayer *device, int bank)
{
#ifdef DISABLE_EMBEDDED_BANKS
    ADL_UNUSED(bank);
    MidiPlayer *play = GET_MIDI_PLAYER(device);
    assert(play);
    play->setErrorString("This build of libADLMIDI has no embedded banks. "
                         "Please load banks by using adl_openBankFile() or "
                         "adl_openBankData() functions instead of adl_setBank().");
    return -1;
#else
    const uint32_t NumBanks = static_cast<uint32_t>(maxAdlBanks());
    int32_t bankno = bank;

    if(bankno < 0)
        bankno = 0;

    MidiPlayer *play = GET_MIDI_PLAYER(device);
    assert(play);
    if(static_cast<uint32_t>(bankno) >= NumBanks)
    {
        char errBuf[150];
        snprintf(errBuf, 150, "Embedded bank number may only be 0..%u!\n", static_cast<unsigned int>(NumBanks - 1));
        play->setErrorString(errBuf);
        return -1;
    }

    play->m_setup.bankId = static_cast<uint32_t>(bankno);
    play->m_synth.setEmbeddedBank(play->m_setup.bankId);
    play->applySetup();

    return adlRefreshNumCards(device);
#endif
}
示例#7
0
ADLMIDI_EXPORT int adl_openFile(ADL_MIDIPlayer *device, const char *filePath)
{
    if(device)
    {
        MidiPlayer *play = GET_MIDI_PLAYER(device);
        assert(play);
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
        play->m_setup.tick_skip_samples_delay = 0;
        if(!play->LoadMIDI(filePath))
        {
            std::string err = play->getErrorString();
            if(err.empty())
                play->setErrorString("ADL MIDI: Can't load file");
            return -1;
        }
        else return 0;
#else
        ADL_UNUSED(filePath);
        play->setErrorString("ADLMIDI: MIDI Sequencer is not supported in this build of library!");
        return -1;
#endif //ADLMIDI_DISABLE_MIDI_SEQUENCER
    }

    ADLMIDI_ErrorString = "Can't load file: ADL MIDI is not initialized";
    return -1;
}
示例#8
0
ADLMIDI_EXPORT const char *adl_metaTrackTitle(struct ADL_MIDIPlayer *device, size_t index)
{
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
    if(!device)
        return "";
    MidiPlayer *play = GET_MIDI_PLAYER(device);
    assert(play);
    const std::vector<std::string> &titles = play->m_sequencer.getTrackTitles();
    if(index >= titles.size())
        return "INVALID";
    return titles[index].c_str();
#else
    ADL_UNUSED(device);
    ADL_UNUSED(index);
    return "NOT SUPPORTED";
#endif
}
示例#9
0
ADLMIDI_EXPORT void adl_positionSeek(struct ADL_MIDIPlayer *device, double seconds)
{
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
    if(seconds < 0.0)
        return;//Seeking negative position is forbidden! :-P
    if(!device)
        return;
    MidiPlayer *play = GET_MIDI_PLAYER(device);
    assert(play);
    play->realTime_panic();
    play->m_setup.delay = play->m_sequencer.seek(seconds, play->m_setup.mindelay);
    play->m_setup.carry = 0.0;
#else
    ADL_UNUSED(device);
    ADL_UNUSED(seconds);
#endif
}
示例#10
0
ADLMIDI_EXPORT int adl_setTriggerHandler(struct ADL_MIDIPlayer *device, ADL_TriggerHandler handler, void *userData)
{
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
    if(!device)
        return -1;
    MidiPlayer *play = GET_MIDI_PLAYER(device);
    assert(play);
    MidiSequencer &seq = play->m_sequencer;
    seq.setTriggerHandler(handler, userData);
    return 0;
#else
    ADL_UNUSED(device);
    ADL_UNUSED(handler);
    ADL_UNUSED(userData);
    return -1;
#endif
}
示例#11
0
ADLMIDI_EXPORT void adl_setLoopEnabled(ADL_MIDIPlayer *device, int loopEn)
{
    if(!device)
        return;
    MidiPlayer *play = GET_MIDI_PLAYER(device);
    assert(play);
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
    play->m_sequencer.setLoopEnabled(loopEn != 0);
#else
    ADL_UNUSED(loopEn);
#endif
}
示例#12
0
ADLMIDI_EXPORT int adl_setTrackOptions(struct ADL_MIDIPlayer *device, size_t trackNumber, unsigned trackOptions)
{
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
    if(!device)
        return -1;
    MidiPlayer *play = GET_MIDI_PLAYER(device);
    assert(play);
    MidiSequencer &seq = play->m_sequencer;

    unsigned enableFlag = trackOptions & 3;
    trackOptions &= ~3u;

    // handle on/off/solo
    switch(enableFlag)
    {
    default:
        break;
    case ADLMIDI_TrackOption_On:
    case ADLMIDI_TrackOption_Off:
        if(!seq.setTrackEnabled(trackNumber, enableFlag == ADLMIDI_TrackOption_On))
            return -1;
        break;
    case ADLMIDI_TrackOption_Solo:
        seq.setSoloTrack(trackNumber);
        break;
    }

    // handle others...
    if(trackOptions != 0)
        return -1;

    return 0;

#else
    ADL_UNUSED(device);
    ADL_UNUSED(trackNumber);
    ADL_UNUSED(trackOptions);
    return -1;
#endif
}
示例#13
0
ADLMIDI_EXPORT double adl_positionTell(struct ADL_MIDIPlayer *device)
{
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
    if(!device)
        return -1.0;
    MidiPlayer *play = GET_MIDI_PLAYER(device);
    assert(play);
    return play->m_sequencer.tell();
#else
    ADL_UNUSED(device);
    return -1.0;
#endif
}
示例#14
0
ADLMIDI_EXPORT size_t adl_metaMarkerCount(struct ADL_MIDIPlayer *device)
{
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
    if(!device)
        return 0;
    MidiPlayer *play = GET_MIDI_PLAYER(device);
    assert(play);
    return play->m_sequencer.getMarkers().size();
#else
    ADL_UNUSED(device);
    return 0;
#endif
}
示例#15
0
ADLMIDI_EXPORT const char *adl_metaMusicCopyright(struct ADL_MIDIPlayer *device)
{
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
    if(!device)
        return "";
    MidiPlayer *play = GET_MIDI_PLAYER(device);
    assert(play);
    return play->m_sequencer.getMusicCopyright().c_str();
#else
    ADL_UNUSED(device);
    return "";
#endif
}
示例#16
0
ADLMIDI_EXPORT void adl_positionRewind(struct ADL_MIDIPlayer *device)
{
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
    if(!device)
        return;
    MidiPlayer *play = GET_MIDI_PLAYER(device);
    assert(play);
    play->realTime_panic();
    play->m_sequencer.rewind();
#else
    ADL_UNUSED(device);
#endif
}
示例#17
0
ADLMIDI_EXPORT int adl_atEnd(struct ADL_MIDIPlayer *device)
{
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
    if(!device)
        return 1;
    MidiPlayer *play = GET_MIDI_PLAYER(device);
    assert(play);
    return (int)play->m_sequencer.positionAtEnd();
#else
    ADL_UNUSED(device);
    return 1;
#endif
}
示例#18
0
ADLMIDI_EXPORT Adl_MarkerEntry adl_metaMarker(struct ADL_MIDIPlayer *device, size_t index)
{
    struct Adl_MarkerEntry marker;

#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
    if(!device)
    {
        marker.label = "INVALID";
        marker.pos_time = 0.0;
        marker.pos_ticks = 0;
        return marker;
    }

    MidiPlayer *play = GET_MIDI_PLAYER(device);
    assert(play);

    const std::vector<MidiSequencer::MIDI_MarkerEntry> &markers = play->m_sequencer.getMarkers();
    if(index >= markers.size())
    {
        marker.label = "INVALID";
        marker.pos_time = 0.0;
        marker.pos_ticks = 0;
        return marker;
    }

    const MidiSequencer::MIDI_MarkerEntry &mk = markers[index];
    marker.label = mk.label.c_str();
    marker.pos_time = mk.pos_time;
    marker.pos_ticks = (unsigned long)mk.pos_ticks;
#else
    ADL_UNUSED(device);
    ADL_UNUSED(index);
    marker.label = "NOT SUPPORTED";
    marker.pos_time = 0.0;
    marker.pos_ticks = 0;
#endif
    return marker;
}
示例#19
0
ADLMIDI_EXPORT int adl_setNumChips(ADL_MIDIPlayer *device, int numChips)
{
    if(device == NULL)
        return -2;

    MidiPlayer *play = GET_MIDI_PLAYER(device);
    assert(play);
#ifdef ADLMIDI_HW_OPL
    ADL_UNUSED(numChips);
    play->m_setup.numChips = 1;
#else
    play->m_setup.numChips = static_cast<unsigned int>(numChips);
#endif
    if(play->m_setup.numChips < 1 || play->m_setup.numChips > MaxChips)
    {
        play->setErrorString("number of chips may only be 1.." MaxChips_STR ".\n");
        return -1;
    }

    play->m_synth.m_numChips = play->m_setup.numChips;
    play->partialReset();

    return adlRefreshNumCards(device);
}
示例#20
0
ADLMIDI_EXPORT int adl_generateFormat(struct ADL_MIDIPlayer *device, int sampleCount,
                                      ADL_UInt8 *out_left, ADL_UInt8 *out_right,
                                      const ADLMIDI_AudioFormat *format)
{
#ifdef ADLMIDI_HW_OPL
    ADL_UNUSED(device);
    ADL_UNUSED(sampleCount);
    ADL_UNUSED(out_left);
    ADL_UNUSED(out_right);
    ADL_UNUSED(format);
    return 0;
#else
    sampleCount -= sampleCount % 2; //Avoid even sample requests
    if(sampleCount < 0)
        return 0;
    if(!device)
        return 0;

    MidiPlayer *player = GET_MIDI_PLAYER(device);
    assert(player);
    MidiPlayer::Setup &setup = player->m_setup;

    ssize_t gotten_len = 0;
    ssize_t n_periodCountStereo = 512;

    int     left = sampleCount;
    double  delay = double(sampleCount) / double(setup.PCM_RATE);

    while(left > 0)
    {
        {//...
            const double eat_delay = delay < setup.maxdelay ? delay : setup.maxdelay;
            delay -= eat_delay;
            setup.carry += double(setup.PCM_RATE) * eat_delay;
            n_periodCountStereo = static_cast<ssize_t>(setup.carry);
            setup.carry -= double(n_periodCountStereo);

            {
                ssize_t leftSamples = left / 2;
                if(n_periodCountStereo > leftSamples)
                    n_periodCountStereo = leftSamples;
                //! 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
                int32_t *out_buf = player->m_outBuf;
                std::memset(out_buf, 0, static_cast<size_t>(in_generatedPhys) * sizeof(out_buf[0]));
                unsigned int chips = player->m_synth.m_numChips;
                if(chips == 1)
                    player->m_synth.m_chips[0]->generate32(out_buf, (size_t)in_generatedStereo);
                else if(n_periodCountStereo > 0)
                {
                    /* Generate data from every chip and mix result */
                    for(unsigned card = 0; card < chips; ++card)
                        player->m_synth.m_chips[card]->generateAndMix32(out_buf, (size_t)in_generatedStereo);
                }
                /* Process it */
                if(SendStereoAudio(sampleCount, in_generatedStereo, out_buf, gotten_len, out_left, out_right, format) == -1)
                    return 0;

                left -= (int)in_generatedPhys;
                gotten_len += (in_generatedPhys) /* - setup.stored_samples*/;
            }

            player->TickIterators(eat_delay);
        }//...
    }

    return static_cast<int>(gotten_len);
#endif
}
示例#21
0
void OPN2::reset(int emulator, unsigned long PCM_RATE, void *audioTickHandler)
{
#if !defined(ADLMIDI_AUDIO_TICK_HANDLER)
    ADL_UNUSED(audioTickHandler);
#endif
    clearChips();
    m_insCache.clear();
    m_regLFOSens.clear();
    m_chips.resize(m_numChips, AdlMIDI_SPtr<OPNChipBase>());

    for(size_t i = 0; i < m_chips.size(); i++)
    {
        OPNChipBase *chip;

        switch(emulator)
        {
        default:
            assert(false);
            abort();
#ifndef OPNMIDI_DISABLE_MAME_EMULATOR
        case OPNMIDI_EMU_MAME:
            chip = new MameOPN2;
            break;
#endif
#ifndef OPNMIDI_DISABLE_NUKED_EMULATOR
        case OPNMIDI_EMU_NUKED:
            chip = new NukedOPN2;
            break;
#endif
#ifndef OPNMIDI_DISABLE_GENS_EMULATOR
        case OPNMIDI_EMU_GENS:
            chip = new GensOPN2;
            break;
#endif
#ifndef OPNMIDI_DISABLE_GX_EMULATOR
        case OPNMIDI_EMU_GX:
            chip = new GXOPN2;
            break;
#endif
        }
        m_chips[i].reset(chip);
        chip->setChipId((uint32_t)i);
        chip->setRate((uint32_t)PCM_RATE, 7670454);
        if(m_runAtPcmRate)
            chip->setRunningAtPcmRate(true);
#if defined(ADLMIDI_AUDIO_TICK_HANDLER)
        chip->setAudioTickHandlerInstance(audioTickHandler);
#endif
    }

    m_numChannels = m_numChips * 6;
    m_insCache.resize(m_numChannels,   m_emptyInstrument.opn[0]);
    m_regLFOSens.resize(m_numChannels,    0);

    uint8_t regLFOSetup = (m_lfoEnable ? 8 : 0) | (m_lfoFrequency & 7);
    m_regLFOSetup = regLFOSetup;

    for(size_t card = 0; card < m_numChips; ++card)
    {
        writeReg(card, 0, 0x22, regLFOSetup);//push current LFO state
        writeReg(card, 0, 0x27, 0x00);  //set Channel 3 normal mode
        writeReg(card, 0, 0x2B, 0x00);  //Disable DAC
        //Shut up all channels
        writeReg(card, 0, 0x28, 0x00 ); //Note Off 0 channel
        writeReg(card, 0, 0x28, 0x01 ); //Note Off 1 channel
        writeReg(card, 0, 0x28, 0x02 ); //Note Off 2 channel
        writeReg(card, 0, 0x28, 0x04 ); //Note Off 3 channel
        writeReg(card, 0, 0x28, 0x05 ); //Note Off 4 channel
        writeReg(card, 0, 0x28, 0x06 ); //Note Off 5 channel
    }

    silenceAll();
}
示例#22
0
ADLMIDI_EXPORT int adl_playFormat(ADL_MIDIPlayer *device, int sampleCount,
                                  ADL_UInt8 *out_left, ADL_UInt8 *out_right,
                                  const ADLMIDI_AudioFormat *format)
{
#if defined(ADLMIDI_DISABLE_MIDI_SEQUENCER) || defined(ADLMIDI_HW_OPL)
    ADL_UNUSED(device);
    ADL_UNUSED(sampleCount);
    ADL_UNUSED(out_left);
    ADL_UNUSED(out_right);
    ADL_UNUSED(format);
    return 0;
#endif

#if !defined(ADLMIDI_DISABLE_MIDI_SEQUENCER) && !defined(ADLMIDI_HW_OPL)
    sampleCount -= sampleCount % 2; //Avoid even sample requests
    if(sampleCount < 0)
        return 0;
    if(!device)
        return 0;

    MidiPlayer *player = GET_MIDI_PLAYER(device);
    assert(player);
    MidiPlayer::Setup &setup = player->m_setup;

    ssize_t gotten_len = 0;
    ssize_t n_periodCountStereo = 512;
    //ssize_t n_periodCountPhys = n_periodCountStereo * 2;
    int left = sampleCount;
    bool hasSkipped = setup.tick_skip_samples_delay > 0;

    while(left > 0)
    {
        {//...
            const double eat_delay = setup.delay < setup.maxdelay ? setup.delay : setup.maxdelay;
            if(hasSkipped)
            {
                size_t samples = setup.tick_skip_samples_delay > sampleCount ? sampleCount : setup.tick_skip_samples_delay;
                n_periodCountStereo = samples / 2;
            }
            else
            {
                setup.delay -= eat_delay;
                setup.carry += double(setup.PCM_RATE) * eat_delay;
                n_periodCountStereo = static_cast<ssize_t>(setup.carry);
                setup.carry -= double(n_periodCountStereo);
            }

            //if(setup.SkipForward > 0)
            //    setup.SkipForward -= 1;
            //else
            {
                if((player->m_sequencer.positionAtEnd()) && (setup.delay <= 0.0))
                    break;//Stop to fetch samples at reaching the song end with disabled loop

                ssize_t leftSamples = left / 2;
                if(n_periodCountStereo > leftSamples)
                {
                    setup.tick_skip_samples_delay = (n_periodCountStereo - leftSamples) * 2;
                    n_periodCountStereo = leftSamples;
                }
                //! 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
                int32_t *out_buf = player->m_outBuf;
                std::memset(out_buf, 0, static_cast<size_t>(in_generatedPhys) * sizeof(out_buf[0]));
                unsigned int chips = player->m_synth.m_numChips;
                if(chips == 1)
                {
                    player->m_synth.m_chips[0]->generate32(out_buf, (size_t)in_generatedStereo);
                }
                else if(n_periodCountStereo > 0)
                {
                    /* Generate data from every chip and mix result */
                    for(size_t card = 0; card < chips; ++card)
                        player->m_synth.m_chips[card]->generateAndMix32(out_buf, (size_t)in_generatedStereo);
                }

                /* Process it */
                if(SendStereoAudio(sampleCount, in_generatedStereo, out_buf, gotten_len, out_left, out_right, format) == -1)
                    return 0;

                left -= (int)in_generatedPhys;
                gotten_len += (in_generatedPhys) /* - setup.stored_samples*/;
            }

            if(hasSkipped)
            {
                setup.tick_skip_samples_delay -= n_periodCountStereo * 2;
                hasSkipped = setup.tick_skip_samples_delay > 0;
            }
            else
                setup.delay = player->Tick(eat_delay, setup.mindelay);

        }//...
    }

    return static_cast<int>(gotten_len);
#endif //ADLMIDI_DISABLE_MIDI_SEQUENCER
}