Ooops. Forgot that file in my last commit.
This commit is contained in:
parent
65d9ca1d92
commit
ce99a65c94
|
@ -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()
|
||||
{
|
||||
}
|
Loading…
Reference in New Issue