Example #1
0
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;
}
Example #2
0
void SoundSystemImpl::queueAudio()
{
#ifdef IMGUI_ENABLE
    const int max_samples = mAudioSpecObtained.samples * mAudioSpecObtained.channels;
    const uint32_t bytePerSample = sizeof(float);
    SDL_AudioDeviceID audioDeviceID = mAudioDeviceId;
    uint32_t alreadyQueuedByte = SDL_GetQueuedAudioSize(audioDeviceID);
    int16_t alreadyQueued = numeric_cast<int16_t>(alreadyQueuedByte / bytePerSample);
    int16_t toQueue = max_samples - alreadyQueued;
    while (g_debug_sample_buffer.max_size() <= g_debug_sample_buffer.size())
    {
        g_debug_sample_buffer.read();
    }
    g_debug_sample_buffer.write(mFrameMixer.size());
    while (g_debug_required_buffer.max_size() <= g_debug_required_buffer.size())
    {
        g_debug_required_buffer.read();
    }
    g_debug_required_buffer.write(toQueue);
#endif

    int audioError = SDL_QueueAudio(audioDeviceID, (const void*)mFrameMixer.data(), mFrameMixer.size() * bytePerSample);
    if (0 != audioError)
    {
        printf("Audio queue error %s\n", SDL_GetError());
    }
    mFrameMixer.clear();
}
Example #3
0
int SNDDMA_AvailableCaptureSamples(void)
{
#ifdef USE_SDL_AUDIO_CAPTURE
	// divided by 2 to convert from bytes to (mono16) samples.
	return sdlCaptureDevice ? (SDL_GetQueuedAudioSize(sdlCaptureDevice) / 2) : 0;
#else
	return 0;
#endif
}
Example #4
0
int16_t SoundSystemImpl::samplesNeeded() const
{
    const int freq = mAudioSpecObtained.freq;
    const int max_samples = mAudioSpecObtained.samples * mAudioSpecObtained.channels;
    const uint32_t bytePerSample = sizeof(float);
    const uint32_t alreadyQueuedByte = SDL_GetQueuedAudioSize(mAudioDeviceId);
    const int16_t alreadyQueued = numeric_cast<int16_t>(alreadyQueuedByte / bytePerSample);
    const int16_t toQueue = max_samples - alreadyQueued;
    return toQueue;
}
Example #5
0
static unsigned int S_CaptureDriverUpdate (void* driverContext, unsigned char* buffer, int minBytes, int maxBytes)
{
	SDL_AudioDeviceID inputdevid = (SDL_AudioDeviceID)driverContext;
	unsigned int available = SDL_GetQueuedAudioSize (inputdevid);

	if (available > minBytes) {
		return SDL_DequeueAudio (inputdevid, buffer, maxBytes);
	}

	return 0;
}
Example #6
0
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;
}
Example #7
0
bool timing_frameskip() {
	// Calculate whether to skip a frame or not
	
	if (conf.audio_api == 0) { // SDL
		// Wait until the audio is drained
		#if SDL_VERSION_ATLEAST(2,0,4)
		while (SDL_GetQueuedAudioSize(dev) > (Uint32)bufsize) {
			if (conf.timing_limiter) { SDL_Delay(1); }
		}
		#endif
	}
	
	static int flipper = 1;
	
	if (altspeed) {
		if (flipper > 2) { flipper = 0; return false; }
		else { flipper++; return true; }
	}
	
	return false;
}
Example #8
0
void
loop()
{
#ifdef __EMSCRIPTEN__
    if (done || (SDL_GetAudioStatus() != SDL_AUDIO_PLAYING)) {
        emscripten_cancel_main_loop();
    }
    else
#endif
    {
        /* The device from SDL_OpenAudio() is always device #1. */
        const Uint32 queued = SDL_GetQueuedAudioSize(1);
        SDL_Log("Device has %u bytes queued.\n", (unsigned int) queued);
        if (queued <= 8192) {  /* time to requeue the whole thing? */
            if (SDL_QueueAudio(1, wave.sound, wave.soundlen) == 0) {
                SDL_Log("Device queued %u more bytes.\n", (unsigned int) wave.soundlen);
            } else {
                SDL_Log("Device FAILED to queue %u more bytes: %s\n", (unsigned int) wave.soundlen, SDL_GetError());
            }
        }
    }
}
Example #9
0
int
main(int argc, char *argv[])
{
    int i;
    char filename[4096];

	/* Enable standard application logging */
	SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);

    /* Load the SDL library */
    if (SDL_Init(SDL_INIT_AUDIO) < 0) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
        return (1);
    }

    if (argc > 1) {
        SDL_strlcpy(filename, argv[1], sizeof(filename));
    } else {
        SDL_strlcpy(filename, "sample.wav", sizeof(filename));
    }
    /* Load the wave file into memory */
    if (SDL_LoadWAV(filename, &wave.spec, &wave.sound, &wave.soundlen) == NULL) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError());
        quit(1);
    }

    wave.spec.callback = NULL;  /* we'll push audio. */

#if HAVE_SIGNAL_H
    /* Set the signals */
#ifdef SIGHUP
    signal(SIGHUP, poked);
#endif
    signal(SIGINT, poked);
#ifdef SIGQUIT
    signal(SIGQUIT, poked);
#endif
    signal(SIGTERM, poked);
#endif /* HAVE_SIGNAL_H */

    /* Initialize fillerup() variables */
    if (SDL_OpenAudio(&wave.spec, NULL) < 0) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open audio: %s\n", SDL_GetError());
        SDL_FreeWAV(wave.sound);
        quit(2);
    }

    /*static x[99999]; SDL_QueueAudio(1, x, sizeof (x));*/

    /* Let the audio run */
    SDL_PauseAudio(0);

    /* Note that we stuff the entire audio buffer into the queue in one
       shot. Most apps would want to feed it a little at a time, as it
       plays, but we're going for simplicity here. */
    
    while (!done && (SDL_GetAudioStatus() == SDL_AUDIO_PLAYING))
    {
        /* The device from SDL_OpenAudio() is always device #1. */
        const Uint32 queued = SDL_GetQueuedAudioSize(1);
        SDL_Log("Device has %u bytes queued.\n", (unsigned int) queued);
        if (queued <= 8192) {  /* time to requeue the whole thing? */
            if (SDL_QueueAudio(1, wave.sound, wave.soundlen) == 0) {
                SDL_Log("Device queued %u more bytes.\n", (unsigned int) wave.soundlen);
            } else {
                SDL_Log("Device FAILED to queue %u more bytes: %s\n", (unsigned int) wave.soundlen, SDL_GetError());
            }
        }

        SDL_Delay(100);  /* let it play for awhile. */
    }

    /* Clean up on signal */
    SDL_CloseAudio();
    SDL_FreeWAV(wave.sound);
    SDL_Quit();
    return 0;
}
Example #10
0
//******************************************************* MAIN *******************************
int main(int argc, char* argv[]){
    //set up sdl
    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);

    SDL_Window *Window = SDL_CreateWindow("Handmade Hero",
        SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
        640, 480, SDL_WINDOW_RESIZABLE);
    if(Window){
        SDL_Renderer *Renderer = SDL_CreateRenderer(Window, -1, 0);
    if(Renderer){

    // VIDEO
    sdl_offscreen_buffer Buffer = {}; // if non-initialized, declaring variables in a loop fails on SDLResizeTexture with a pointer error - im blaming the compiler
    sdl_window_dimension Dimension = SDLGetWindowDimension(Window);
    SDLResizeTexture(&Buffer, Renderer, Dimension.Width, Dimension.Height);
    keystates Keys = {};

    //AUDIO
    sdl_sound_output sound_output = sdl_sound_outputH(48000);
    //open audio
    SDLInitAudio(sound_output.SamplesPerSecond, sound_output.SamplesPerSecond * sound_output.BytesPerSample / 60);
    SDL_PauseAudio(0);

    //BW: state area allocation
    void *new_state_area = malloc(128*1024*1024);//need ~2 MB at least; give it 128 MiB -- 2MB for video; dont know audio
    void *prev_state_area = malloc(1024);// should be sizeof(state0), or sizeof(biggest statetype) later
    //apparently we didnt have enough memory, but only crashed sometimes? this fixed it
    void *state;
    
    {
        uint8 *next_ptr = (uint8*)prev_state_area;
        anim_comp *animation = (anim_comp*)next_ptr;
        next_ptr += sizeof(anim_comp);

        init_anim_comp(animation, 0,0);

        state0 *stateptr = (state0*)next_ptr;
        printf("state0 size %ld\n", sizeof(state0));
        uint64 stateptrn = (uint64)stateptr;
        uint64 sizeptr = (uint64)&(stateptr->size);
        uint64 deepc_ptr = (uint64)&(stateptr->deep_count);
        uint64 anim_ptr = (uint64)&(stateptr->animation);
        uint64 tsine_ptr = (uint64)&(stateptr->tSine);
        uint64 tvol_ptr = (uint64)&(stateptr->ToneVolume);
        uint64 thz_ptr = (uint64)&(stateptr->ToneHz);
        uint64 pu_ptr = (uint64)&(stateptr->pitch_up_was_pressed);
        printf("offset begin    %lu\n", sizeptr - stateptrn);
        printf("width of size   %lu\n", deepc_ptr - sizeptr);
        printf("width of deepc  %lu\n", anim_ptr - deepc_ptr);
        printf("width of animpt %lu\n", tsine_ptr - anim_ptr);
        printf("width of tsine  %lu\n", tvol_ptr - tsine_ptr);
        printf("width of tvol   %lu\n", thz_ptr - tvol_ptr);
        printf("width of thz    %lu\n", pu_ptr - thz_ptr);

        next_ptr += sizeof(state0);

        init_state0(stateptr, animation, 3000, 256, 0);

        state = stateptr;
        //return 0;
    }

    uint64 LastCounter = SDL_GetPerformanceCounter();
    uint64 LastCycleCount = _rdtsc();
    uint64 PerfCountFrequency = SDL_GetPerformanceFrequency();

    bool running = true;
    //main loop
    printf("enter main event loop\n");
    while(running){
        ///////NP_UPDATE/////////////
        //event capturing
        event_return events = eventHandler(&Keys);
        if(events.shouldQuit) running = false;
        //setup for p
        state_window_info Wi = {}; Wi.Height = Buffer.Height; Wi.Width = Buffer.Width; Wi.Pitch = Buffer.Pitch;
        int TargetQueueBytes = sound_output.LatencySampleCount * sound_output.BytesPerSample;
        state_sound_info Si = {}; Si.BytesToGet = TargetQueueBytes - SDL_GetQueuedAudioSize(1); Si.BytesPerSample = sound_output.BytesPerSample; Si.SamplesPerSecond = sound_output.SamplesPerSecond;
        uint64 state_size = 0;
        uint64 vbuffer_size = Buffer.Height * Buffer.Pitch;
        uint64 abuffer_size = Si.BytesToGet;
        state_return next;
        { //in case(statetype) or similar
            next = P_update_state0(*(state0*)state, new_state_area, Keys, Wi, Si);
            //p should return state_size? and also, what statetype we are in -> later
            state_size = sizeof(state0);
        }

        //GARBAGE COLLECTOR
        //move this state to previous state
        //fmemcpy(prev_state_area, new_state_area, state_size); //shallow copy, as supposed
        //printf("hi\n");
        deepcopy(prev_state_area, next.state, new_state_area, (uint8*)new_state_area + 128*1024*1024);
        //TODO(md): DEEPCPY

        //queue audio
        if (Si.BytesToGet > 0) SDL_QueueAudio(1, next.abuffer, abuffer_size);

        //render
        SDLUpdateWindow(Window, Renderer, Buffer, next.vbuffer);


        uint64 EndCycleCount = _rdtsc();
        uint64 EndCounter = SDL_GetPerformanceCounter();
        uint64 CounterElapsed = EndCounter - LastCounter;
        uint64 CyclesElapsed = EndCycleCount - LastCycleCount;

        real64 MSPerFrame = (((1000.0f * (real64)CounterElapsed) / (real64)PerfCountFrequency));
        real64 FPS = (real64)PerfCountFrequency / (real64)CounterElapsed;
        real64 MCPF = ((real64)CyclesElapsed / (1000.0f * 1000.0f));

        printf("%.02fms/f, %.02f/s, %.02fmc/f\n", MSPerFrame, FPS, MCPF);

        LastCycleCount = EndCycleCount;
        LastCounter = EndCounter;
    }
    } } //if(Renderer, Window)
    SDL_Quit();
    return 0;
}
Example #11
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;
}