#include #include #include #include #include #include #include #include #include #include using namespace std; #include "mythcontext.h" #include "audiooutputpulse.h" #include "util.h" AudioOutputPULSE::AudioOutputPULSE( QString laudio_main_device, QString laudio_passthru_device, int laudio_bits, int laudio_channels, int laudio_samplerate, AudioOutputSource lsource, bool lset_initial_vol, bool laudio_passthru) : AudioOutputBase(laudio_main_device, laudio_passthru_device, laudio_bits, laudio_channels, laudio_samplerate, lsource, lset_initial_vol, laudio_passthru), buff_size(-1), can_hw_pause(false) { s = false; playing = false; closing = false; // Set everything up Reconfigure(laudio_bits, laudio_channels, laudio_samplerate, laudio_passthru); } AudioOutputPULSE::~AudioOutputPULSE() { // Close down all audio stuff CloseDevice(); } bool AudioOutputPULSE::OpenDevice() { VERBOSE(VB_AUDIO, QString("Opening PULSE audio device.")); CloseDevice(); VERBOSE(VB_AUDIO, QString("Continue Opening PULSE audio device.")); if (audio_bits == 16) { ss.format = PA_SAMPLE_S16LE; VERBOSE(VB_AUDIO, QString("PULSE with PA_SAMPLE_S16LE.")); } else { ss.format = PA_SAMPLE_FLOAT32LE; VERBOSE(VB_AUDIO, QString("PULSE with PA_SAMPLE_FLOAT32LE.")); } ss.channels = audio_channels; VERBOSE(VB_AUDIO, QString("PULSE with %1 channels.").arg(audio_channels)); ss.rate = audio_samplerate; VERBOSE(VB_AUDIO, QString("PULSE with %1 samplerate.").arg(audio_samplerate)); int error; s = pa_simple_new(NULL, // Use the default server. "MythMusic", // Our application's name. PA_STREAM_PLAYBACK, NULL, // Use the default device. "Music", // Description of our stream. &ss, // Our sample format. NULL, // Use default channel map NULL, // Use default buffering attributes. &error // Ignore error code. ); fragment_size = 1024; if (!s) { Error(QString(" pa_simple_new() failed (%1)").arg(error)); Error(QString(" pa_simple_new() failed: %1").arg(pa_strerror(error))); CloseDevice(); return false; } // Setup volume control if (internal_vol) VolumeInit(); // Device opened successfully return true; } void AudioOutputPULSE::CloseDevice() { if (!s) { return; } closing = true; VERBOSE(VB_AUDIO, QString("Entering closing PULSE audio device.")); while(playing) { usleep(1000); } VERBOSE(VB_AUDIO, QString("Closing PULSE audio device.")); pa_simple *s2 = s; s = false; pa_simple_free(s2); closing = false; VERBOSE(VB_AUDIO, QString("Done closing PULSE audio device.")); } void AudioOutputPULSE::WriteAudio(unsigned char *aubuf, int size) { if (!s) { return; } if (closing) { return; } VERBOSE(VB_AUDIO, QString("Writing to PULSE: buffer size %1").arg(size)); int error; playing = true; if (pa_simple_write(s, aubuf, size, &error) < 0) { playing = false; Error(QString(" pa_simple_write() failed: %1").arg(pa_strerror(error))); return; } playing = false; VERBOSE(VB_AUDIO, QString("Done writing to PULSE: buffer size %1").arg(size)); } inline int AudioOutputPULSE::getBufferedOnSoundcard(void) { return 0; //return JACK_GetBytesStored(audioid) + fragment_size * 2; } inline int AudioOutputPULSE::getSpaceOnSoundcard(void) { return 1024; } void AudioOutputPULSE::VolumeInit(void) { } int AudioOutputPULSE::GetVolumeChannel(int channel) { return 100; } void AudioOutputPULSE::SetVolumeChannel(int channel, int volume) { }