void AudioManager::Start() { if(mbIsInitialized) { return; } mbIsInitialized = true; star::Logger::GetInstance()->Log(star::LogLevel::Info, _T("Audio : Started making Audio Engine"), STARENGINE_LOG_TAG); #ifdef DESKTOP int32 audio_rate(44100); uint16 audio_format(MIX_DEFAULT_FORMAT); int32 audio_channels(2); int32 audio_buffers(4096); SDL_Init(SDL_INIT_AUDIO); int32 flags = MIX_INIT_OGG | MIX_INIT_MP3; int32 innited = Mix_Init(flags); if((innited & flags) != flags) { star::Logger::GetInstance()->Log(star::LogLevel::Info, _T("Audio :Could not init Ogg and Mp3, reason : ") + string_cast<tstring>(Mix_GetError()), STARENGINE_LOG_TAG); } if(Mix_OpenAudio(audio_rate, audio_format,audio_channels,audio_buffers)) { star::Logger::GetInstance()->Log(star::LogLevel::Info, _T("Audio : Could Not open Audio Mix SDL"), STARENGINE_LOG_TAG); Stop(); return; } Mix_AllocateChannels(16); //check What we got int32 actual_rate, actual_channels; uint16 actual_format; Mix_QuerySpec(&actual_rate,&actual_format,&actual_channels); tstringstream buffer; buffer << "Actual Rate : " << actual_rate; buffer << ", Actual Format : " << actual_format; buffer << ", Actual Channels : " << actual_channels; buffer << std::endl; star::Logger::GetInstance()->Log(star::LogLevel::Info, _T("Audio : SDL specs : ") + buffer.str(), STARENGINE_LOG_TAG); Mix_Volume(-1,100); #else SLresult lRes; const SLuint32 lEngineMixIIDCount = 1; const SLInterfaceID lEngineMixIIDs[] = { SL_IID_ENGINE }; const SLboolean lEngineMixReqs[] = { SL_BOOLEAN_TRUE }; const SLuint32 lOutputMixIIDCount= 1; const SLInterfaceID lOutputMixIIDs[] = { SL_IID_VOLUME }; const SLboolean lOutputMixReqs[] = { SL_BOOLEAN_FALSE}; lRes = slCreateEngine( &mEngineObj, 0, NULL, lEngineMixIIDCount, lEngineMixIIDs, lEngineMixReqs ); if(lRes != SL_RESULT_SUCCESS) { star::Logger::GetInstance()->Log(star::LogLevel::Error, _T("Audio : Can't make Audio Engine"), STARENGINE_LOG_TAG); Stop(); return; } lRes = (*mEngineObj)->Realize(mEngineObj, SL_BOOLEAN_FALSE); if(lRes != SL_RESULT_SUCCESS) { star::Logger::GetInstance()->Log(star::LogLevel::Error, _T("Audio : Can't realize Engine"), STARENGINE_LOG_TAG); Stop(); return; } lRes = (*mEngineObj)->GetInterface( mEngineObj, SL_IID_ENGINE, &mEngine ); if(lRes != SL_RESULT_SUCCESS) { star::Logger::GetInstance()->Log(star::LogLevel::Error, _T("Audio : Can't fetch engine interface"), STARENGINE_LOG_TAG); Stop(); return; } lRes = (*mEngine)->CreateOutputMix( mEngine, &mOutputMixObj, lOutputMixIIDCount, lOutputMixIIDs, lOutputMixReqs ); if(lRes != SL_RESULT_SUCCESS) { star::Logger::GetInstance()->Log(star::LogLevel::Error, _T("Audio : Can't create outputmix"), STARENGINE_LOG_TAG); Stop(); return; } lRes = (*mOutputMixObj)->Realize(mOutputMixObj,SL_BOOLEAN_FALSE); if(lRes != SL_RESULT_SUCCESS) { star::Logger::GetInstance()->Log(star::LogLevel::Error, _T("Audio : Can't realise output object"), STARENGINE_LOG_TAG); Stop(); return; } lRes = (*mOutputMixObj)->GetInterface( mOutputMixObj, SL_IID_VOLUME, &mOutputMixVolume ); if(lRes != SL_RESULT_SUCCESS) { star::Logger::GetInstance()->Log(star::LogLevel::Warning, _T("Audio : Can't get volume interface!"), STARENGINE_LOG_TAG); mOutputMixVolume = nullptr; } star::Logger::GetInstance()->Log(star::LogLevel::Info, _T("Audio : Succesfull made Audio Engine"), STARENGINE_LOG_TAG); #endif }
BYTE snd_start(void) { int psamples; if (!cfg->apu.channel[APU_MASTER]) { return (EXIT_OK); } // come prima cosa blocco eventuali riproduzioni snd_stop(); memset(&snd, 0x00, sizeof(_snd)); memset(&xaudio2, 0x00, sizeof(xaudio2)); memset(&cbd, 0x00, sizeof(_callback_data)); snd.cache = &cbd; audio_channels(cfg->channels_mode); switch (cfg->samplerate) { case S48000: snd.samplerate = 48000; break; case S44100: snd.samplerate = 44100; break; case S22050: snd.samplerate = 22050; break; case S11025: snd.samplerate = 11025; break; } if (XAudio2Create(&xaudio2.engine, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) { MessageBox(NULL, "ATTENTION: Unable to create XAudio2 object. Probably you\n" "have an incomplete installation of DirectX 10." , "Error!", MB_ICONEXCLAMATION | MB_OK); return (EXIT_ERROR); } if (IXAudio2_CreateMasteringVoice(xaudio2.engine, &xaudio2.master, snd.channels, snd.samplerate, 0, 0, NULL) != S_OK) { MessageBox(NULL, "ATTENTION: Unable to create XAudio2 master voice.", "Error!", MB_ICONEXCLAMATION | MB_OK); return (EXIT_ERROR); } { WAVEFORMATEX wfm; memset(&wfm, 0, sizeof(wfm)); wfm.wFormatTag = WAVE_FORMAT_PCM; wfm.nChannels = snd.channels; wfm.wBitsPerSample = 16; wfm.nSamplesPerSec = snd.samplerate; wfm.nBlockAlign = (wfm.nChannels * wfm.wBitsPerSample) / 8; wfm.nAvgBytesPerSec = wfm.nSamplesPerSec * wfm.nBlockAlign; wfm.cbSize = sizeof(wfm); if (IXAudio2_CreateSourceVoice(xaudio2.engine, &xaudio2.source, &wfm, XAUDIO2_VOICE_NOSRC | XAUDIO2_VOICE_NOPITCH, XAUDIO2_DEFAULT_FREQ_RATIO, &callbacks, NULL, NULL) != S_OK) { MessageBox(NULL, "ATTENTION: Unable to create XAudio2 source voice.\n", "Error!", MB_ICONEXCLAMATION | MB_OK); return (EXIT_ERROR); } } { double factor = (1.0f / 48000.0f) * (double) snd.samplerate; psamples = ((1024 * factor) + ((512 * factor) * cfg->audio_buffer_factor)); } snd.samples = psamples * 2; snd.frequency = machine.cpu_hz / (double) snd.samplerate; xaudio2.opened = TRUE; #if !defined (RELEASE) xaudio2.tick = gui_get_ms(); #endif { // dimensione in bytes del buffer snd.buffer.size = (psamples * snd.channels * sizeof(*cbd.write)) * 5; snd.buffer.limit.low = (snd.buffer.size / 100) * 25; snd.buffer.limit.high = (snd.buffer.size / 100) * 55; #if !defined (RELEASE) printf("softw bsize : %-6d - %-6d\n", snd.buffer.size, snd.samples); printf("softw limit : %-6d - %-6d\n", snd.buffer.limit.low, snd.buffer.limit.high); #endif // alloco il buffer in memoria if (!(cbd.start = (SWORD *) malloc(snd.buffer.size))) { MessageBox(NULL, "ATTENTION: Unable to allocate audio buffers.\n", "Error!", MB_ICONEXCLAMATION | MB_OK); return (EXIT_ERROR); } if (!(cbd.silence = (SWORD *) malloc(snd.buffer.size))) { MessageBox(NULL, "ATTENTION: Unable to allocate silence buffer.\n", "Error!", MB_ICONEXCLAMATION | MB_OK); return (EXIT_ERROR); } // inizializzo il frame di scrittura cbd.write = cbd.start; // inizializzo il frame di lettura cbd.read = (SBYTE *) cbd.start; // punto alla fine del buffer cbd.end = cbd.read + snd.buffer.size; // creo il lock if ((xaudio2.semaphore = CreateSemaphore(NULL, 1, 2, NULL)) == NULL) { MessageBox(NULL, "ATTENTION: Unable to create XAudio2 semaphore.\n", "Error!", MB_ICONEXCLAMATION | MB_OK); return (EXIT_ERROR); } // azzero completamente i buffers memset(cbd.start, 0x00, snd.buffer.size); // azzero completamente il buffer del silenzio memset(cbd.silence, 0x00, snd.buffer.size); // azzero completamente la struttura XAUDIO2_BUFFER memset(&xaudio2.buffer, 0x00, sizeof(xaudio2.buffer)); xaudio2.buffer.AudioBytes = psamples * sizeof(*cbd.write) * snd.channels; //xaudio2.buffer.pAudioData = (const BYTE *) cbd.read; xaudio2.buffer.pAudioData = (const BYTE *) cbd.silence; xaudio2.buffer.PlayBegin = 0; xaudio2.buffer.PlayLength = psamples; xaudio2.buffer.LoopBegin = 0; xaudio2.buffer.LoopLength = 0; xaudio2.buffer.LoopCount = 0; xaudio2.buffer.pContext = snd.cache; cbd.xa2buffer = &xaudio2.buffer; cbd.xa2source = xaudio2.source; cbd.lock = xaudio2.semaphore; if (IXAudio2SourceVoice_SubmitSourceBuffer(xaudio2.source, (const XAUDIO2_BUFFER *) cbd.xa2buffer, NULL) != S_OK) { MessageBox(NULL, "ATTENTION: Unable to set sound engine.\n", "Error!", MB_ICONEXCLAMATION | MB_OK); return (EXIT_ERROR); } } if (extcl_snd_start) { extcl_snd_start((WORD) snd.samplerate); } audio_channels_init_mode(); audio_quality(cfg->audio_quality); if(IXAudio2_StartEngine(xaudio2.engine) != S_OK) { MessageBox(NULL, "ATTENTION: Unable to start sound engine.\n", "Error!", MB_ICONEXCLAMATION | MB_OK); return (EXIT_ERROR); } if(IXAudio2SourceVoice_Start(xaudio2.source, 0, XAUDIO2_COMMIT_NOW) != S_OK) { MessageBox(NULL, "ATTENTION: Unable to start source voice.\n", "Error!", MB_ICONEXCLAMATION | MB_OK); return (EXIT_ERROR); } return (EXIT_OK); }