diff options
author | Jerome Fisher | 2004-11-14 04:13:15 +0000 |
---|---|---|
committer | Jerome Fisher | 2004-11-14 04:13:15 +0000 |
commit | 1aeca6838b1ba5405674d0f5e38174fe6dedd138 (patch) | |
tree | 29452d977920959157474f6902c12d456b96c83a /backends/midi/mt32/synth.cpp | |
parent | 5e442766e533339c1e2f3389a2859601c6ab1127 (diff) | |
download | scummvm-rg350-1aeca6838b1ba5405674d0f5e38174fe6dedd138.tar.gz scummvm-rg350-1aeca6838b1ba5405674d0f5e38174fe6dedd138.tar.bz2 scummvm-rg350-1aeca6838b1ba5405674d0f5e38174fe6dedd138.zip |
MT32 MidiDriver:
- Cleanup
MT32Emu:
- Lots more cleanup.
- Properly implemented pitch bending (not fast, but theoretically perfect).
- Full position delta is now calculated before PCM interpolation/decimation is performed, so that pitch modifiers will be considered.
- Now reports when using SSE or 3DNow, and when the samplerate is invalid.
svn-id: r15801
Diffstat (limited to 'backends/midi/mt32/synth.cpp')
-rw-r--r-- | backends/midi/mt32/synth.cpp | 118 |
1 files changed, 62 insertions, 56 deletions
diff --git a/backends/midi/mt32/synth.cpp b/backends/midi/mt32/synth.cpp index 2647fdae85..4c697b893f 100644 --- a/backends/midi/mt32/synth.cpp +++ b/backends/midi/mt32/synth.cpp @@ -19,21 +19,16 @@ * IN THE SOFTWARE. */ -#define BENCHMARK 0 - #include <math.h> #include <string.h> #include <stdlib.h> #include <errno.h> -#if BENCHMARK > 0 -#include <time.h> -#endif #include "mt32emu.h" -// Debugging stuff -// Used to dump drum patches to syx file for viewing -#define DUMPDRUMS 0 +#if MT32EMU_BENCHMARK_FILTERS > 0 +#include <time.h> +#endif namespace MT32Emu { @@ -347,7 +342,8 @@ bool Synth::loadPCMToROMMap(const char *filename) { return false; } - for (int i=0;i<54;i++) { + Bit32u PCMReassign[54]; + for (int i = 0; i < 54; i++) { PCMReassign[i] = i; PCM[i].tune = 220.0f; PCM[i].ampval = 256; @@ -378,6 +374,8 @@ bool Synth::loadPCMToROMMap(const char *filename) { if (cp != NULL) { cp = strtok(NULL," \n\r"); if (cp != NULL) { + strncpy(PCM[patchcount].name, cp, 15); + PCM[patchcount].name[15] = 0; cp = strtok(NULL," \n\r"); if (cp !=NULL) { int newpcm = atoi(cp); @@ -581,7 +579,7 @@ bool Synth::open(SynthProperties &useProp) { return false; } -#if DUMPDRUMS == 1 +#if MT32EMU_DUMP_DRUMS == 1 strcpy(&pathBuf[0], baseDir); dumpDrums(strcat(&pathBuf[0],"drumsys.syx")); #endif @@ -605,12 +603,14 @@ bool Synth::open(SynthProperties &useProp) { mt32ram.params.patches[i].timbreNum = i & 63; } - TableInitialiser tableInitialiser; - tableInitialiser.initMT32Tables(this, PCM, (float)myProp.SampleRate); - if (myProp.UseDefault) - initReverb(0,5); + if (!TableInitialiser::initMT32Tables(this, PCM, (float)myProp.sampleRate)) { + report(ReportType_errorSampleRate, NULL); + return false; + } + if (myProp.useDefaultReverb) + initReverb(0, 5); else - initReverb(myProp.RevType, myProp.RevTime); + initReverb(myProp.reverbType, myProp.reverbTime); for (int i = 0; i < 9; i++) { parts[i] = new Part(this, i); @@ -619,14 +619,14 @@ bool Synth::open(SynthProperties &useProp) { // The patch is already set by the presets, now set the timbre it wants parts[i]->setTimbre(&mt32ram.params.timbres[parts[i]->getAbsTimbreNum()].timbre); // And refresh the part's cache - parts[i]->RefreshPatch(); + parts[i]->refreshPatch(); } } // For resetting mt32 mid-execution mt32default = mt32ram; -#ifdef HAVE_X86 +#ifdef MT32EMU_HAVE_X86 bool availableSSE = DetectSIMD(); bool available3DNow = Detect3DNow(); @@ -646,7 +646,7 @@ bool Synth::open(SynthProperties &useProp) { } #endif -#if BENCHMARK > 1 +#if MT32EMU_BENCHMARK_FILTERS > 1 // Benchmark 3DNow, Floating point, and SSE filters clock_t start, end; float histval[50]; @@ -691,7 +691,7 @@ void Synth::close(void) { return; for (int t = 0; t < 4; t++) { - for (int m = 0; m < 128; m++) { + for (int m = 0; m < NUM_NOTES; m++) { if (waveforms[t][m]!=NULL) { delete[] waveforms[t][m]; waveforms[t][m] = NULL; @@ -743,51 +743,52 @@ void Synth::playMsgOnPart(unsigned char part, unsigned char code, unsigned char case 0x8: //printDebug("Note OFF - Part %d", part); // The MT-32 ignores velocity for note off - parts[part]->StopNote(note); + parts[part]->stopNote(note); break; case 0x9: //printDebug("Note ON - Part %d, Note %d Vel %d", part, note, velocity); if (velocity == 0) { // MIDI defines note-on with velocity 0 as being the same as note-off with velocity 40 - parts[part]->StopNote(note); + parts[part]->stopNote(note); } else { - parts[part]->PlayNote(partialManager, note, velocity); + parts[part]->playNote(partialManager, note, velocity); } break; case 0xB: // Control change switch (note) { case 0x01: // Modulation //printDebug("Modulation: %d", velocity); - parts[part]->SetModulation(velocity); - break; - case 0x0B: - //printDebug("Expression set: %d", velocity); - parts[part]->SetVolume(velocity); + parts[part]->setModulation(velocity); break; case 0x07: // Set volume //if (part!=3) return; //printDebug("Volume set: %d", velocity); - parts[part]->SetVolume(velocity); + parts[part]->setVolume(velocity); break; case 0x0A: // Pan //printDebug("Pan set: %d", velocity); - parts[part]->SetPan(velocity); + parts[part]->setPan(velocity); + break; + case 0x0B: + //printDebug("Expression set: %d", velocity); + parts[part]->setVolume(velocity); break; case 0x40: // Hold pedal //printDebug("Hold pedal set: %d", velocity); - parts[part]->SetHoldPedal(velocity>=64); + parts[part]->setHoldPedal(velocity>=64); break; - case 0x7B: // All notes off - //printDebug("All notes off"); - parts[part]->AllStop(); - break; case 0x79: // Reset all controllers printDebug("Reset all controllers (NYI)"); break; + case 0x7B: // All notes off + //printDebug("All notes off"); + parts[part]->allStop(); + break; + default: - printDebug("Unknown MIDI Control code: 0x%02x - vel %02x",note, velocity); + printDebug("Unknown MIDI Control code: 0x%02x - vel 0x%02x", note, velocity); break; } @@ -795,7 +796,7 @@ void Synth::playMsgOnPart(unsigned char part, unsigned char code, unsigned char case 0xC: // Program change //printDebug("Program change %01x", note); if (part < 8) { - parts[part]->SetPatch(note); + parts[part]->setPatch(note); } else { printDebug("Program change attempted on rhythm part"); } @@ -803,7 +804,7 @@ void Synth::playMsgOnPart(unsigned char part, unsigned char code, unsigned char case 0xE: // Pitch bender bend = (velocity << 7) | (note); //printDebug("Pitch bender %02x", bend); - parts[part]->SetBend(bend); + parts[part]->setBend(bend); break; default: printDebug("Unknown Midi code: 0x%01x - %02x - %02x", code, note, velocity); @@ -936,8 +937,13 @@ void Synth::playSysexWithoutHeader(unsigned char device, Bit8u *sysex, Bit32u le timbreName[10] = 0; printDebug("WRITE-PARTPATCH (%d-%d@%d..%d): %d; timbre=%d (%s)", firstPart, lastPart, off, off + len, i, absTimbreNum, timbreName); if (parts[i] != NULL) { - parts[i]->setTimbre(&mt32ram.params.timbres[parts[i]->getAbsTimbreNum()].timbre); - parts[i]->RefreshPatch(); + if (i == firstPart && off > 2) { + printDebug(" (Not updating timbre, since those values weren't touched)"); + } else { + // Not sure whether we should do this at all, really. + parts[i]->setTimbre(&mt32ram.params.timbres[parts[i]->getAbsTimbreNum()].timbre); + } + parts[i]->refreshPatch(); } } } else if (addr >= MEMADDR(0x030110) && addr < MEMADDR(0x040000)) { @@ -963,7 +969,7 @@ void Synth::playSysexWithoutHeader(unsigned char device, Bit8u *sysex, Bit32u le printDebug("WRITE-RHYTHM (%d-%d@%d..%d): %d; level=%02x, panpot=%02x, reverb=%02x, timbre=%d (%s)", firstDrum, lastDrum, off, off + len, i, mt32ram.params.rhythmSettings[i].outlevel, mt32ram.params.rhythmSettings[i].panpot, mt32ram.params.rhythmSettings[i].reverbSwitch, mt32ram.params.rhythmSettings[i].timbre, timbreName); } if (parts[8] != NULL) { - parts[8]->RefreshDrumCache(); + parts[8]->refreshDrumCache(); } } else if (addr >= MEMADDR(0x040000) && addr < MEMADDR(0x050000)) { int off = addr - MEMADDR(0x040000); @@ -982,7 +988,7 @@ void Synth::playSysexWithoutHeader(unsigned char device, Bit8u *sysex, Bit32u le instrumentName[10] = 0; printDebug("WRITE-PARTTIMBRE (%d-%d@%d..%d): timbre=%d (%s)", firstPart, lastPart, off, off + len, i, instrumentName); if (parts[i] != NULL) { - parts[i]->RefreshPatch(); + parts[i]->refreshPatch(); } } } @@ -1053,12 +1059,12 @@ void Synth::playSysexWithoutHeader(unsigned char device, Bit8u *sysex, Bit32u le // Does the real MT-32 automatically do this? if (i >= 128 && parts[8] != NULL) { // FIXME:KG: Only bother to re-cache when this timbre's actually in the rhythm map - parts[8]->SetPatch(i); // Re-cache this timbre + parts[8]->setPatch(i); // Re-cache this timbre } for (unsigned int part = 0; part < 8; part++) { if (parts[part] != NULL) { if (parts[part]->getAbsTimbreNum() == i) { - parts[part]->RefreshPatch(); + parts[part]->refreshPatch(); } } } @@ -1080,7 +1086,7 @@ void Synth::playSysexWithoutHeader(unsigned char device, Bit8u *sysex, Bit32u le for (unsigned int i = 0; i < 9; i++) { //LOG(LOG_MISC|LOG_ERROR,"Part %d set to MIDI channel %d",i,mt32ram.params.system.chanAssign[i]); if (mt32ram.params.system.chanAssign[i] == 16) { - parts[i]->AllStop(); + parts[i]->allStop(); } else { chantable[(int)mt32ram.params.system.chanAssign[i]] = (char)i; } @@ -1093,12 +1099,12 @@ void Synth::playSysexWithoutHeader(unsigned char device, Bit8u *sysex, Bit32u le report(ReportType_newReverbLevel, &mt32ram.params.system.reverbLevel); if ((mt32ram.params.system.reverbMode != curRevMode) || (mt32ram.params.system.reverbTime != curRevTime)) { - if (myProp.UseDefault) { + if (myProp.useDefaultReverb) { initReverb(mt32ram.params.system.reverbMode, mt32ram.params.system.reverbTime); curRevLevel = mt32ram.params.system.reverbLevel; } else { - initReverb(myProp.RevType, myProp.RevTime); - curRevLevel = myProp.RevLevel; + initReverb(myProp.reverbType, myProp.reverbTime); + curRevLevel = myProp.reverbLevel; } } @@ -1127,9 +1133,9 @@ void Synth::playSysexWithoutHeader(unsigned char device, Bit8u *sysex, Bit32u le partialManager->DeactivateAll(); mt32ram = mt32default; for (int i = 0; i < 8; i++) { - parts[i]->RefreshPatch(); + parts[i]->refreshPatch(); } - parts[8]->RefreshDrumCache(); + parts[8]->refreshDrumCache(); isEnabled = false; } else { printDebug("Sysex write to unrecognised address %06x", SYSEXMEMADDR(addr)); @@ -1195,7 +1201,7 @@ int Synth::dumpSysex(char *filename) { } void ProduceOutput1(Bit16s *useBuf, Bit16s *stream, Bit32u len, Bit16s volume) { -#if USE_MMX > 2 +#if MT32EMU_USE_MMX > 2 //FIXME:KG: This appears to introduce crackle int donelen = i386_produceOutput1(useBuf, stream, len, volume); len -= donelen; @@ -1226,9 +1232,9 @@ void Synth::doRender(Bit16s * stream,Bit32u len) { partialManager->AgeAll(); - if (myProp.UseReverb) { + if (myProp.useReverb) { bool hasOutput = false; - for (unsigned int i = 0; i < MAXPARTIALS; i++) { + for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) { if (partialManager->shouldReverb(i)) { if (partialManager->ProduceOutput(i, &tmpBuffer[0], len)) { ProduceOutput1(&tmpBuffer[0], stream, len, mastervolume); @@ -1254,7 +1260,7 @@ void Synth::doRender(Bit16s * stream,Bit32u len) { m++; } } - for (unsigned int i = 0; i < MAXPARTIALS; i++) { + for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) { if (!partialManager->shouldReverb(i)) { if (partialManager->ProduceOutput(i, &tmpBuffer[0], len)) { ProduceOutput1(&tmpBuffer[0], stream, len, mastervolume); @@ -1262,7 +1268,7 @@ void Synth::doRender(Bit16s * stream,Bit32u len) { } } } else { - for (unsigned int i = 0; i < MAXPARTIALS; i++) { + for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) { if (partialManager->ProduceOutput(i, &tmpBuffer[0], len)) ProduceOutput1(&tmpBuffer[0], stream, len, mastervolume); } @@ -1270,14 +1276,14 @@ void Synth::doRender(Bit16s * stream,Bit32u len) { partialManager->ClearAlreadyOutputed(); -#if MONITORPARTIALS == 1 +#if MT32EMU_MONITOR_PARTIALS == 1 samplepos += len; if (samplepos > myProp.SampleRate * 5) { samplepos = 0; int partialUsage[9]; partialManager->GetPerPartPartialUsage(partialUsage); printDebug("1:%02d 2:%02d 3:%02d 4:%02d 5:%02d 6:%02d 7:%02d 8:%02d", partialUsage[0], partialUsage[1], partialUsage[2], partialUsage[3], partialUsage[4], partialUsage[5], partialUsage[6], partialUsage[7]); - printDebug("Rhythm: %02d TOTAL: %02d", partialUsage[8], MAXPARTIALS - partialManager->GetFreePartialCount()); + printDebug("Rhythm: %02d TOTAL: %02d", partialUsage[8], MT32EMU_MAX_PARTIALS - partialManager->GetFreePartialCount()); } #endif } |