int osd_update_audio_stream(INT16 *buffer) { // Soundcard switch off? if (Machine->sample_rate == 0) return samples_per_frame; Uint32 unBytesQueued = SDL_GetQueuedAudioSize(audio_device); if (unBytesQueued == 0) { ++fifo_underrun; // Queue some silence to start buffering uint8_t silence[bytes_per_frame]; memset(silence, 0, sizeof(silence)); SDL_QueueAudio(audio_device, silence, sizeof(silence)); } if (unBytesQueued > 10*bytes_per_frame) { ++fifo_overrun; SDL_ClearQueuedAudio(audio_device); } profiler_mark(PROFILER_USER1); if (attenuation < 0) { /* FIXME: Need to attenuate the audio stream? */ } SDL_QueueAudio(audio_device, buffer, bytes_per_frame); profiler_mark(PROFILER_END); return samples_per_frame; }
void timing_set_default() { // Set the framerate to the default altspeed = false; framerate = nst_pal ? (conf.timing_speed / 6) * 5 : conf.timing_speed; #if SDL_VERSION_ATLEAST(2,0,4) if (conf.audio_api == 0) { SDL_ClearQueuedAudio(dev); } #endif }
void SNDDMA_StartCapture(void) { #ifdef USE_SDL_AUDIO_CAPTURE if (sdlCaptureDevice) { SDL_ClearQueuedAudio(sdlCaptureDevice); SDL_PauseAudioDevice(sdlCaptureDevice, 0); } #endif }
void audio_play() { if (paused) { updateok = true; return; } bufsize = 2 * channels * (conf.audio_sample_rate / framerate); if (conf.audio_api == 0) { // SDL #if SDL_VERSION_ATLEAST(2,0,4) SDL_QueueAudio(dev, (const void*)audiobuf, bufsize); // Clear the audio queue arbitrarily to avoid it backing up too far if (SDL_GetQueuedAudioSize(dev) > (Uint32)(bufsize * 3)) { SDL_ClearQueuedAudio(dev); } #endif } #ifndef _MINGW else if (conf.audio_api == 1) { // libao ao_play(aodevice, (char*)audiobuf, bufsize); } #endif updateok = true; }
/* attenuation in dB */ void osd_set_mastervolume(int _attenuation) { // clamp the attenuation to 0-32 range if (_attenuation > 0) { attenuation = 0; } else if (_attenuation < -32) { attenuation = -32; } else { attenuation = _attenuation; } if (Machine->sample_rate > 0) { if (attenuation == -32) { SDL_PauseAudioDevice(audio_device, 1); SDL_ClearQueuedAudio(audio_device); } else { SDL_PauseAudioDevice(audio_device, 0); } } }
void loop(NES nesSystem, const char * fileLoc) { if (!init_sdl(fileLoc)) { std::cerr << "SDL did not initialize, quitting" << std::endl; return; } Debugger debugger(&nesSystem); //game loop variables double frequency = SDL_GetPerformanceFrequency(); uintmax_t startTime = SDL_GetPerformanceCounter(); bool paused = true; SDL_Event event; for (int x = 0; x < 256 * 240; x++) localPixels[x] = 0; draw(nesSystem.m_nesCPU.m_nesPPU.m_pixels); //draw screen black SDL_PauseAudioDevice(sdlAudioDevice, 0); //unpause audio for (;;) { //1 process events if (!process_events(&event, &nesSystem.m_nesCPU.m_controllerByte, &paused)) { break; } //2 logic if (!paused) { do { enum DebuggerEventStatus debugEventStatus = debugger.pre_instr_events(); if (debugEventStatus == BREAK_HIT || debugEventStatus == CRASH_IMMINENT) { paused = true; break; } else if (debugEventStatus == DONE_LOGGED_EXECUTION) { paused = true; } //execute one cpu opcode nesSystem.m_nesCPU.execute_next_opcode(); debugger.post_instr_events(); //ppu catches up nesSystem.m_nesCPU.m_nesPPU.tick(&nesSystem.m_nesCPU.m_NMI, &nesSystem.m_nesCPU.m_cpuClock); } while (!nesSystem.m_nesCPU.m_nesPPU.m_draw && !paused); //3.1 audio nesSystem.m_nesCPU.m_nesAPU.fill_buffer(&nesSystem, &nesSystem.m_nesCPU.m_IRQ); if (SDL_GetQueuedAudioSize(sdlAudioDevice) > (unsigned int) nesSystem.m_nesCPU.m_nesAPU.m_audioBufferSize * 10) { //prevents audio from becoming too out of sync SDL_ClearQueuedAudio(sdlAudioDevice); } SDL_QueueAudio(sdlAudioDevice, (void *) nesSystem.m_nesCPU.m_nesAPU.m_audioBuffer, nesSystem.m_nesCPU.m_nesAPU.m_audioBufferSize); } else { enum DebuggerCommandStatus commandStatus; do { commandStatus = debugger.cmd(); } while (commandStatus == CONTINUE_DEBUG); //SDL_FlushEvents(SDL_USEREVENT, SDL_LASTEVENT); if (commandStatus == RUN_NO_FOCUS) { paused = false; } else if (commandStatus == QUIT) { break; } else if (commandStatus == RUN_RETURN_FOCUS) { paused = false; SDL_RaiseWindow(window); } else { break; } } //3.2 video draw(nesSystem.m_nesCPU.m_nesPPU.m_pixels); //4 sync framerate double delay = MILLISECONDS_PER_FRAME - (((SDL_GetPerformanceCounter() - startTime) / frequency) * 1000) - 0.5; if (delay > 0) { std::this_thread::sleep_for(std::chrono::microseconds((int) (delay * 1000))); } while ((((SDL_GetPerformanceCounter() - startTime) / frequency) * 1000) < MILLISECONDS_PER_FRAME) { } startTime = SDL_GetPerformanceCounter(); } SDL_PauseAudioDevice(sdlAudioDevice, 1); //pause SDL_ClearQueuedAudio(sdlAudioDevice); //clear audio queue close_sdl(); return; }