* Fix paCallback decleration

* Switch from PaOpenDefaultStream to Pa_OpenStream.
* Add Debug output
* Add GetOutputDevices which returns a list of available devices (unused)

Originally committed to SVN as r2796.
This commit is contained in:
Amar Takhar 2009-04-15 10:26:22 +00:00
parent 558be555e2
commit aa85b2eb01
2 changed files with 61 additions and 13 deletions

View File

@ -64,11 +64,13 @@ PortAudioPlayer::PortAudioPlayer() {
// Initialize portaudio // Initialize portaudio
if (!pa_refcount) { if (!pa_refcount) {
PaError err = Pa_Initialize(); PaError err = Pa_Initialize();
if (err != paNoError) { if (err != paNoError) {
static wchar_t errormsg[2048]; static wchar_t errormsg[2048];
swprintf(errormsg, 2048, L"Failed opening PortAudio: %s", Pa_GetErrorText(err)); swprintf(errormsg, 2048, L"Failed opening PortAudio: %s", Pa_GetErrorText(err));
throw (const wchar_t *)errormsg; throw (const wchar_t *)errormsg;
} }
pa_refcount++; pa_refcount++;
} }
@ -88,9 +90,8 @@ PortAudioPlayer::~PortAudioPlayer() {
} }
////////////////////// //////////////////////
// PortAudio callback /// PortAudio callback
int PortAudioPlayer::paCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData) {
int PortAudioPlayer::paCallback(void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData) {
// Get provider // Get provider
PortAudioPlayer *player = (PortAudioPlayer *) userData; PortAudioPlayer *player = (PortAudioPlayer *) userData;
@ -128,7 +129,13 @@ PortAudioPlayer::~PortAudioPlayer() {
player->playPos += framesPerBuffer; player->playPos += framesPerBuffer;
const PaStreamInfo* streamInfo = Pa_GetStreamInfo(player->stream); const PaStreamInfo* streamInfo = Pa_GetStreamInfo(player->stream);
player->realPlayPos = (timeInfo->outputBufferDacTime * streamInfo->sampleRate) + player->startPos; player->realPlayPos = (timeInfo->inputBufferAdcTime * streamInfo->sampleRate) + player->startPos;
/*
printf("playPos: %lld startPos: %lld paStart: %f currentTime: %f realPlayPos: %lld Pa_GetStreamTime: %f AdcTime: %f DacTime: %f\n",
player->playPos, player->startPos, player->paStart, timeInfo->currentTime, player->realPlayPos, Pa_GetStreamTime(player->stream),
timeInfo->inputBufferAdcTime, timeInfo->outputBufferDacTime);
*/
// Cap to start if lower // Cap to start if lower
return end; return end;
@ -183,9 +190,27 @@ void PortAudioPlayer::Stop(bool timerToo) {
// Open stream // Open stream
void PortAudioPlayer::OpenStream() { void PortAudioPlayer::OpenStream() {
// Open stream // Open stream
PaError err = Pa_OpenDefaultStream(&stream,0,provider->GetChannels(),paInt16,provider->GetSampleRate(),256,paCallback,this); PaStreamParameters pa_output_p;
PaDeviceIndex pa_device = Pa_GetDefaultOutputDevice();
pa_output_p.device = pa_device;
pa_output_p.channelCount = provider->GetChannels();
pa_output_p.sampleFormat = paInt16;
pa_output_p.suggestedLatency = Pa_GetDeviceInfo(pa_device)->defaultLowOutputLatency;
pa_output_p.hostApiSpecificStreamInfo = NULL;
wxLogDebug(_T("PortAudioPlayer::OpenStream Output Device: %d, Output channels: %d, Latency: %f Sample Rate: %ld\n"),
pa_device, pa_output_p.channelCount, pa_output_p.suggestedLatency, pa_output_p.sampleFormat);
PaError err = Pa_OpenStream(&stream, NULL, &pa_output_p, provider->GetSampleRate(), 256, paNoFlag, paCallback, this);
if (err != paNoError) { if (err != paNoError) {
const PaHostErrorInfo *pa_err = Pa_GetLastHostErrorInfo();
if (pa_err->errorCode != 0) {
wxLogDebug(_T("PortAudioPlayer::OpenStream HostError: API: %d, %s (%ld)\n"), pa_err->hostApiType, pa_err->errorText, pa_err->errorCode);
}
throw wxString(_T("Failed initializing PortAudio stream with error: ") + wxString(Pa_GetErrorText(err),wxConvLocal)); throw wxString(_T("Failed initializing PortAudio stream with error: ") + wxString(Pa_GetErrorText(err),wxConvLocal));
} }
} }
@ -201,4 +226,25 @@ void PortAudioPlayer::CloseStream() {
} }
///////////////
/// Return a list of available output devices.
/// @param Setting from config file.
wxArrayString PortAudioPlayer::GetOutputDevices(wxString favorite) {
wxArrayString list;
int devices = Pa_GetDeviceCount();
int i;
if (devices < 0) {
// some error here
}
for (i=0; i<devices; i++) {
const PaDeviceInfo *dev_info = Pa_GetDeviceInfo(i);
wxString name(dev_info->name, wxConvUTF8);
list.Insert(name, i);
}
return list;
}
#endif // WITH_PORTAUDIO2 #endif // WITH_PORTAUDIO2

View File

@ -66,14 +66,15 @@ private:
PaTime paStart; PaTime paStart;
volatile int64_t realPlayPos; volatile int64_t realPlayPos;
// static int paCallback(void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, PaTime outTime, void *userData); static int paCallback(
static int paCallback(void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData); const void *inputBuffer,
/* void *outputBuffer,
static int paCallback(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer, unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo *timei, const PaStreamCallbackTimeInfo*
PaStreamCallbackFlags flags, void *userData); timeInfo,
*/ PaStreamCallbackFlags
statusFlags,
void *userData);
public: public:
PortAudioPlayer(); PortAudioPlayer();
@ -95,6 +96,7 @@ public:
void SetVolume(double vol) { volume = vol; } void SetVolume(double vol) { volume = vol; }
double GetVolume() { return volume; } double GetVolume() { return volume; }
wxArrayString GetOutputDevices(wxString favorite=0);
wxMutex *GetMutex() { return &PAMutex; } wxMutex *GetMutex() { return &PAMutex; }
}; };