From: bruceperens Date: Tue, 11 Mar 2014 03:40:18 +0000 (+0000) Subject: Fill in audio_out_alsa X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=200b1ae9c4c074e34fb856b6b334be51ed6d352b;p=freetel-svn-tracking.git Fill in audio_out_alsa git-svn-id: https://svn.code.sf.net/p/freetel/code@1422 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/freedv-server/source/platform/linux/alsa.cpp b/freedv-server/source/platform/linux/alsa.cpp index 5dface70..f2aa5215 100644 --- a/freedv-server/source/platform/linux/alsa.cpp +++ b/freedv-server/source/platform/linux/alsa.cpp @@ -61,9 +61,9 @@ namespace FreeDV { stream << std::endl; if ( ctl_error == 0 ) { - snd_ctl_close(ctl_handle); - if ( pcm_error == 0 ) + if ( pcm_error == 0 ) snd_pcm_close(pcm_handle); + snd_ctl_close(ctl_handle); } } } diff --git a/freedv-server/source/platform/linux/audio_out_alsa.cpp b/freedv-server/source/platform/linux/audio_out_alsa.cpp index 623dd234..0e30537e 100644 --- a/freedv-server/source/platform/linux/audio_out_alsa.cpp +++ b/freedv-server/source/platform/linux/audio_out_alsa.cpp @@ -1,5 +1,6 @@ /// The ALSA audio output driver. +#include #include "drivers.h" #include #include @@ -12,8 +13,20 @@ namespace FreeDV { /// Audio output "ALSA", Uses the Linux ALSA Audio API. class AudioOutALSA : public AudioOutput { private: - snd_pcm_t * handle; + char * const parameters; + snd_pcm_t * handle; + volatile void + do_throw(const int error, const char * message = 0) + { + std::ostringstream str; + + str << "Error on ALSA audio output " << parameters << ": "; + if ( message ) + str << message << ": "; + str << snd_strerror(error); + throw std::runtime_error(str.str().c_str()); + } public: /// Instantiate the audio output. @@ -31,32 +44,56 @@ namespace FreeDV { }; AudioOutALSA::AudioOutALSA(const char * p) - : AudioOutput("alsa", p) + : AudioOutput("alsa", p), parameters(strdup(p)) { - const int error = snd_pcm_open( + const snd_pcm_format_t format = SND_PCM_FORMAT_S16; + const snd_pcm_access_t access = SND_PCM_ACCESS_RW_INTERLEAVED; + const unsigned int channels = 1; + const unsigned int rate = 48000; + const int soft_resample = 0; + const unsigned int latency = 0; + int error; + + handle = 0; + error = snd_pcm_open( &handle, p, SND_PCM_STREAM_PLAYBACK, 0); - if ( error ) { - std::ostringstream str; - - str << "Can't open audio device " << p << ": " << snd_strerror(error); - throw std::runtime_error(str.str().c_str()); - } + if ( error != 0 ) + do_throw(error, "Open"); + + if ( (error = snd_pcm_set_params( + handle, + format, + access, + channels, + rate, + soft_resample, + latency)) < 0 ) + do_throw(error, "Set Parameters"); + + if ( (error = snd_pcm_prepare(handle)) < 0 ) + do_throw(error, "Prepare"); } AudioOutALSA::~AudioOutALSA() { + snd_pcm_drop(handle); snd_pcm_close(handle); + free(parameters); } // Write audio into the "short" type. std::size_t AudioOutALSA::write16(const std::int16_t * array, std::size_t length) { - return length; + const int result = snd_pcm_writei(handle, array, length); + if ( result >= 0 ) + return result; + else + do_throw(result, "Write"); } AudioOutput * @@ -76,10 +113,10 @@ namespace FreeDV { { snd_pcm_sframes_t available = 0; - if ( (available = snd_pcm_avail(handle)) <= 0 ) + if ( (available = snd_pcm_avail(handle)) >= 0 ) return available; else - return 0; + do_throw(available, "Get Available Frames"); } static bool