Ooops. Forgot that file in my last commit.

This commit is contained in:
bgk 2008-04-20 07:33:58 +00:00
parent 65d9ca1d92
commit ce99a65c94
1 changed files with 181 additions and 0 deletions

181
src/gtk/sndPortAudio.cpp Normal file
View File

@ -0,0 +1,181 @@
#include <stdio.h>
#include <string.h>
#include <portaudio.h>
#ifndef _WIN32
# include <unistd.h>
#else
# include <Windows.h>
#endif
#include "../System.h"
#include "../Sound.h"
#include "../Globals.h"
extern int emulating;
bool systemSoundOn = false;
static PaStreamParameters outputParameters;
static PaStream *stream;
static PaError err;
static u16 *stereodata16;
static u32 soundoffset;
static volatile u32 soundpos;
static u32 soundbufsize;
static int audioFree()
{
if (soundoffset > soundpos)
return soundbufsize - soundoffset + soundpos;
else
return soundpos - soundoffset;
}
static int patestCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
const int outBufferLength = framesPerBuffer * sizeof(u16) * 2;
u8 *out = (u8*)outputBuffer;
if (!emulating || soundPaused)
{
memset(out, 0, outBufferLength);
return paContinue;
}
if (soundbufsize - audioFree() < outBufferLength)
fprintf(stderr, "** PortAudio : buffer underflow **\n");
u8 *soundbuf = (u8 *)stereodata16;
for (int i = 0; i < outBufferLength; i++)
{
if (soundpos >= soundbufsize)
soundpos = 0;
out[i] = soundbuf[soundpos];
soundpos++;
}
return paContinue;
}
void systemWriteDataToSoundBuffer()
{
u32 copy1size = 0, copy2size = 0;
while (emulating && !speedup & !systemThrottle && (audioFree() < soundBufferLen))
{
#ifndef _WIN32
usleep(1000);
#else
Sleep(1);
#endif
}
if ((soundbufsize - soundoffset) < soundBufferLen)
{
copy1size = (soundbufsize - soundoffset);
copy2size = soundBufferLen - copy1size;
}
else
{
copy1size = soundBufferLen;
copy2size = 0;
}
memcpy((((u8 *)stereodata16)+soundoffset), soundFinalWave, copy1size);
if (copy2size)
memcpy(stereodata16, ((u8 *)soundFinalWave)+copy1size, copy2size);
soundoffset += copy1size + copy2size;
soundoffset %= soundbufsize;
}
bool systemSoundInit()
{
int sampleRate;
int buffersize = 0;
err = Pa_Initialize();
if (err != paNoError) goto error;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = paInt16;
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
switch(soundQuality) {
case 1:
sampleRate = 44100;
soundBufferLen = 1470*2;
break;
case 2:
sampleRate = 22050;
soundBufferLen = 736*2;
break;
case 4:
sampleRate = 11025;
soundBufferLen = 368*2;
break;
}
soundbufsize = (soundBufferLen + 1) * 4;
fprintf(stderr, "i %d %d\n", soundbufsize, sampleRate);
stereodata16 = new u16[soundbufsize];
memset(stereodata16, 0, soundbufsize);
soundpos = 0;
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
sampleRate,
0,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
patestCallback,
NULL );
if (err != paNoError) goto error;
err = Pa_StartStream( stream );
if (err != paNoError) goto error;
systemSoundOn = true;
return true;
error:
Pa_Terminate();
fprintf(stderr, "An error occured while using the portaudio stream\n");
fprintf(stderr, "Error number: %d\n", err);
fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err));
return false;
}
void systemSoundShutdown()
{
Pa_CloseStream(stream);
Pa_Terminate();
delete[] stereodata16;
}
void systemSoundPause()
{
}
void systemSoundResume()
{
}
void systemSoundReset()
{
}