/** * \brief Opens, checks current audio status, and closes a device. * * \sa https://wiki.libsdl.org/SDL_GetAudioStatus */ int audio_openCloseAndGetAudioStatus() { SDL_AudioStatus result; int i; int count; char *device; SDL_AudioDeviceID id; SDL_AudioSpec desired, obtained; /* Get number of devices. */ count = SDL_GetNumAudioDevices(0); SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)"); if (count > 0) { for (i = 0; i < count; i++) { /* Get device name */ device = (char *)SDL_GetAudioDeviceName(i, 0); SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i); SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL"); if (device == NULL) return TEST_ABORTED; /* Set standard desired spec */ desired.freq=22050; desired.format=AUDIO_S16SYS; desired.channels=2; desired.samples=4096; desired.callback=_audio_testCallback; desired.userdata=NULL; /* Open device */ id = SDL_OpenAudioDevice((const char *)device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device); SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >=2, got: %i", id); if (id > 1) { /* Check device audio status */ result = SDL_GetAudioDeviceStatus(id); SDLTest_AssertPass("Call to SDL_GetAudioDeviceStatus()"); SDLTest_AssertCheck(result == SDL_AUDIO_STOPPED || result == SDL_AUDIO_PLAYING || result == SDL_AUDIO_PAUSED, "Verify returned value; expected: STOPPED (%i) | PLAYING (%i) | PAUSED (%i), got: %i", SDL_AUDIO_STOPPED, SDL_AUDIO_PLAYING, SDL_AUDIO_PAUSED, result); /* Close device again */ SDL_CloseAudioDevice(id); SDLTest_AssertPass("Call to SDL_CloseAudioDevice()"); } } } else { SDLTest_Log("No devices to test with"); } return TEST_COMPLETED; }
void SoundSDL::write(uint16_t * finalWave, int length) { if (!_initialized) return; if (SDL_GetAudioDeviceStatus(_dev) != SDL_AUDIO_PLAYING) SDL_PauseAudioDevice(_dev, 0); SDL_mutexP(_mutex); unsigned int samples = length / 4; std::size_t avail; while ((avail = _rbuf.avail() / 2) < samples) { bool lock = (emulating && !speedup && throttle && !gba_joybus_active) ? true : false; _rbuf.write(finalWave, avail * 2); finalWave += avail * 2; samples -= avail; SDL_mutexV(_mutex); SDL_SemPost(_semBufferFull); if (lock) { SDL_SemWait(_semBufferEmpty); if (throttle > 0 && throttle != current_rate) { SDL_CloseAudio(); init(soundGetSampleRate() * throttle / 100); current_rate = throttle; } } else { // Drop the remaining of the audio data return; } SDL_mutexP(_mutex); } _rbuf.write(finalWave, samples * 2); SDL_mutexV(_mutex); }
static void loop() { SDL_bool please_quit = SDL_FALSE; SDL_Event e; while (SDL_PollEvent(&e)) { if (e.type == SDL_QUIT) { please_quit = SDL_TRUE; } else if (e.type == SDL_KEYDOWN) { if (e.key.keysym.sym == SDLK_ESCAPE) { please_quit = SDL_TRUE; } } else if (e.type == SDL_MOUSEBUTTONDOWN) { if (e.button.button == 1) { SDL_PauseAudioDevice(devid_out, SDL_TRUE); SDL_PauseAudioDevice(devid_in, SDL_FALSE); } } else if (e.type == SDL_MOUSEBUTTONUP) { if (e.button.button == 1) { SDL_PauseAudioDevice(devid_in, SDL_TRUE); SDL_PauseAudioDevice(devid_out, SDL_FALSE); } } } if (SDL_GetAudioDeviceStatus(devid_in) == SDL_AUDIO_PLAYING) { SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255); } else { SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); } SDL_RenderClear(renderer); SDL_RenderPresent(renderer); if (please_quit) { /* stop playing back, quit. */ SDL_Log("Shutting down.\n"); SDL_PauseAudioDevice(devid_in, 1); SDL_CloseAudioDevice(devid_in); SDL_PauseAudioDevice(devid_out, 1); SDL_CloseAudioDevice(devid_out); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); #ifdef __EMSCRIPTEN__ emscripten_cancel_main_loop(); #endif exit(0); } /* Note that it would be easier to just have a one-line function that calls SDL_QueueAudio() as a capture device callback, but we're trying to test the API, so we use SDL_DequeueAudio() here. */ while (SDL_TRUE) { Uint8 buf[1024]; const Uint32 br = SDL_DequeueAudio(devid_in, buf, sizeof (buf)); SDL_QueueAudio(devid_out, buf, br); if (br < sizeof (buf)) { break; } } }