#include #include "mungal4.h" #pragma hdrstop #include "l4audlvl.h" #include "l4audres.h" #include "..\munga\audrend.h" #include "..\munga\objstrm.h" #include "..\munga\namelist.h" #include "openal/al.h" //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PatchLevelOfDetail ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #if DEBUG_LEVEL>0 TableOf PatchLevelOfDetail::patchTableSocket(NULL, True); #endif // //############################################################################# //############################################################################# // PatchLevelOfDetail::PatchLevelOfDetail(PlugStream *stream): AudioLevelOfDetail(stream) { MemoryStream_Read(stream, &bankID); MemoryStream_Read(stream, &patchID); MemoryStream_Read(stream, &maxMIDIFilterCutoff); Warn(GetVoiceCount() > 4); // HACK - AWE appears to only play 1st 4 voices #ifdef LAB_ONLY setupCount = 0; #endif // // Keep table of created patchs to verify that duplicates // are not created, could move this to tool time // #if DEBUG_LEVEL>0 unsigned int index_value = (bankID * 1000) + patchID; if (patchTableSocket.Find(index_value) != NULL) { Dump((int)bankID); Dump((int)patchID); } Verify(patchTableSocket.Find(index_value) == NULL); patchTableSocket.AddValue(this, index_value); #endif } // //############################################################################# //############################################################################# // void PatchLevelOfDetail::BuildFromPage( PlugStream *stream, NameList *name_list, ClassID class_ID, ObjectID object_ID ) { AudioLevelOfDetail::BuildFromPage(stream, name_list, class_ID, object_ID); // // Store fields // MEM_STRM_WRITE_ENTRY(*stream, name_list, SBKBankID, bank_ID); MEM_STRM_WRITE_ENTRY(*stream, name_list, SBKPatchID, patch_ID); MEM_STRM_WRITE_ENTRY(*stream, name_list, MIDINRPNValue, max_filter_cutoff); } // //############################################################################# //############################################################################# // PatchLevelOfDetail::~PatchLevelOfDetail() { #ifdef LAB_ONLY cout << "PatchLevelOfDetail::~PatchLevelOfDetail\t"; cout << (int)bankID << ":" << (int)patchID << "\t"; cout << "setupCount=\t" << setupCount << "\n"; #endif /*if (m_numSources > 0 && m_sources != NULL) { for (int i=0; i < m_numSources; i++) { //Detach buffer alSourcei(m_sources[i],AL_BUFFER,0); //Stop source ALenum state; alGetSourcei(m_sources[i],AL_SOURCE_STATE,&state); if (state == AL_PLAYING) { alSourceStop(m_sources[i]); } } //Destroy all sources alDeleteSources(m_numSources,m_sources); }*/ } // //############################################################################# //############################################################################# // Logical PatchLevelOfDetail::TestInstance() const { AudioLevelOfDetail::TestInstance(); return True; } // //############################################################################# //############################################################################# // void PatchLevelOfDetail::SetupPatch(SourceSet sourceSet) { // Check(this); //// Check(channel); // // #ifdef LAB_ONLY // setupCount++; // #endif SAMPLEINFO info; //Attach buffers for (int i=0; i < sourceSet.count; i++) { info = PRESET_getSampleInfo(bankID,patchID,i); if (info.bufferIndex >= 0) { ALenum sourceState; alGetSourcei(sourceSet.sources[i], AL_SOURCE_STATE, &sourceState); if (getenv("BT_AUDIO_SPATIAL")) { static int s_se=0; if (s_se++<200) DEBUG_STREAM << "[audio] SetupPatch ENTRY bank=" << (int)bankID << " patch=" << (int)patchID << " src=" << sourceSet.sources[i] << " file=" << (info.file?info.file:"?") << " state=" << sourceState << " (INITIAL=" << AL_INITIAL << ")" << "\n" << std::flush; } if (sourceState == AL_INITIAL) { alSourcei(sourceSet.sources[i],AL_BUFFER,AL_getBuffer(info.bufferIndex)); { static int s_a=0; if (getenv("BT_AUDIO_LOG") && s_a++<24) DEBUG_STREAM << "[audio] SetupPatch src=" << sourceSet.sources[i] << " file=" << (info.file?info.file:"?") << " loop=" << (info.loop==ForceStatic?0:1) << "\n" << std::flush; } alSourcei(sourceSet.sources[i],AL_SOURCE_RELATIVE,AL_TRUE); AudioRenderer *render = application->GetAudioRenderer(); AudioHead *head = render->GetAudioHead(); alSource3f(sourceSet.sources[i],AL_POSITION,0,0,0); alSource3f(sourceSet.sources[i],AL_VELOCITY,0,0,0); if (info.loop == ForceStatic) { alSourcei(sourceSet.sources[i],AL_LOOPING,0); } else { alSourcei(sourceSet.sources[i],AL_LOOPING,1); } } } } // // Set the channel to the bank and program, reset patch controls // /* channel->SelectBank(bankID); channel->SendProgramChange(patchID); channel->SendController(MIDI_CONTROL_RESET, MIDI_MAX_CONTROL_VALUE);*/ //TODO: Sync up OpenAL source info appropriately /*#if 0 Tell((int)bankID << ":" << (int)patchID << "\n"); #endif*/ } void PatchLevelOfDetail::PlayNote(SourceSet sourceSet) { if (sourceSet.count > 0 && sourceSet.sources != NULL) { alGetError(); //DEBUG_STREAM << "Playing bank " << (int)bankID << ", patch " << (int)patchID << std::endl; for (int i = 0; i < sourceSet.count; i++) { ALenum state; alGetSourcei(sourceSet.sources[i], AL_SOURCE_STATE, &state); if (state != AL_PLAYING) { alSourcePlay(sourceSet.sources[i]); { static int s_p=0; if (getenv("BT_AUDIO_LOG") && s_p++<30) DEBUG_STREAM << "[audio] PlayNote alSourcePlay src=" << sourceSet.sources[i] << "\n" << std::flush; } } ALenum error = alGetError(); if (error != AL_NO_ERROR) { DEBUG_STREAM << "Playing hit an error: " << error << std::endl; return; } } } } void PatchLevelOfDetail::StopNote(SourceSet sourceSet) { if (getenv("BT_AUDIO_LOG")) { static int s_s=0; if (s_s++<400) { DEBUG_STREAM << "[audio] StopNote"; for (int _i=0;_i0 && sourceSet.sources != NULL) { alSourceStopv(sourceSet.count, sourceSet.sources); alSourceRewindv(sourceSet.count, sourceSet.sources); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PatchResource ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // //############################################################################# //############################################################################# // PatchResource::PatchResource(PlugStream *stream): AudioResource(stream) { } // //############################################################################# //############################################################################# // void PatchResource::BuildFromPage( PlugStream *stream, NameList *name_list, ClassID class_ID, ObjectID object_ID ) { AudioResource::BuildFromPage(stream, name_list, class_ID, object_ID); } // //############################################################################# //############################################################################# // PatchResource::~PatchResource() { } // //############################################################################# //############################################################################# // Logical PatchResource::TestInstance() const { AudioResource::TestInstance(); return True; } // //############################################################################# //############################################################################# // void PatchResource::SetupPatch(SourceSet sourceSet) { Check(this); // Check(channel); PatchLevelOfDetail *patch_level_of_detail = Cast_Object(PatchLevelOfDetail*, GetAudioLevelOfDetail()); Check(patch_level_of_detail); patch_level_of_detail->SetupPatch(sourceSet); } void PatchResource::PlayNote(SourceSet sourceSet) { Check(this); // Check(channel); PatchLevelOfDetail *patch_level_of_detail = Cast_Object(PatchLevelOfDetail*, GetAudioLevelOfDetail()); Check(patch_level_of_detail); patch_level_of_detail->PlayNote(sourceSet); } void PatchResource::StopNote(SourceSet sourceSet) { Check(this); // Check(channel); PatchLevelOfDetail *patch_level_of_detail = Cast_Object(PatchLevelOfDetail*, GetAudioLevelOfDetail()); Check(patch_level_of_detail); patch_level_of_detail->StopNote(sourceSet); } // //############################################################################# //############################################################################# // MIDINRPNValue PatchResource::GetMaxMIDIFilterCutoff() { Check(this); PatchLevelOfDetail *patch_level_of_detail = Cast_Object(PatchLevelOfDetail*, GetAudioLevelOfDetail()); Check(patch_level_of_detail); return patch_level_of_detail->GetMaxMIDIFilterCutoff(); }