Skip to content
Snippets Groups Projects
Commit 68310c6b authored by Rafaël Carré's avatar Rafaël Carré
Browse files

* #6629: simplify AlsaLayer::alsa_set_params()

remove unneeded class members
fix a bug with samplerate
parent cdf78f78
No related branches found
No related tags found
No related merge requests found
...@@ -80,7 +80,6 @@ AlsaLayer::AlsaLayer () ...@@ -80,7 +80,6 @@ AlsaLayer::AlsaLayer ()
, playbackHandle_ (NULL) , playbackHandle_ (NULL)
, ringtoneHandle_ (NULL) , ringtoneHandle_ (NULL)
, captureHandle_ (NULL) , captureHandle_ (NULL)
, periodSize_ (160)
, audioPlugin_ (audioPref.getPlugin()) , audioPlugin_ (audioPref.getPlugin())
, IDSoundCards_ () , IDSoundCards_ ()
, is_playback_prepared_ (false) , is_playback_prepared_ (false)
...@@ -314,115 +313,45 @@ void AlsaLayer::preparePlaybackStream (void) ...@@ -314,115 +313,45 @@ void AlsaLayer::preparePlaybackStream (void)
bool AlsaLayer::alsa_set_params (snd_pcm_t *pcm_handle) bool AlsaLayer::alsa_set_params (snd_pcm_t *pcm_handle)
{ {
snd_pcm_hw_params_t *hwparams = NULL; #define TRY(call, error) do { \
snd_pcm_sw_params_t *swparams = NULL; int err = call; \
int format; if (err < 0) { \
int periods = 4; _error("ALSA: Cannot set "error": %s", snd_strerror(err)); \
int periodsize = 160; return false; \
} \
/* Allocate the snd_pcm_hw_params_t struct */ } while(0)
snd_pcm_hw_params_malloc (&hwparams);
snd_pcm_hw_params_t *hwparams;
periodSize_ = periodsize; snd_pcm_hw_params_alloca(&hwparams);
/* Full configuration space */
snd_pcm_uframes_t periodSize = 160;
int err; unsigned int periods = 4;
if ((err = snd_pcm_hw_params_any (pcm_handle, hwparams)) < 0) {
_debug ("Audio: Error: Cannot initialize hardware parameter structure (%s)", snd_strerror (err)); #define HW pcm_handle, hwparams /* hardware parameters */
return false; TRY(snd_pcm_hw_params_any (HW), "hwparams init");
} TRY(snd_pcm_hw_params_set_access (HW, SND_PCM_ACCESS_RW_INTERLEAVED), "access type");
TRY(snd_pcm_hw_params_set_format (HW, SND_PCM_FORMAT_S16_LE), "sample format");
if ((err = snd_pcm_hw_params_set_access (pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { TRY(snd_pcm_hw_params_set_rate_near (HW, &audioSampleRate_, NULL), "sample rate");
_debug ("Audio: Error: Cannot set access type (%s)", snd_strerror (err)); TRY(snd_pcm_hw_params_set_channels (HW, 1), "channel count");
return false; TRY(snd_pcm_hw_params_set_period_size_near (HW, &periodSize, NULL), "period time");
} TRY(snd_pcm_hw_params_set_periods_near (HW, &periods, NULL), "periods number");
TRY(snd_pcm_hw_params (HW), "hwparams");
/* Set sample format */ #undef HW
format = SND_PCM_FORMAT_S16_LE;
_debug ("ALSA: Using sampling rate %dHz", audioSampleRate_);
if ((err = snd_pcm_hw_params_set_format (pcm_handle, hwparams, (snd_pcm_format_t) format)) < 0) {
_debug ("Audio: Error: Cannot set sample format (%s)", snd_strerror (err));
return false;
}
/* Set sample rate. If we can't set to the desired exact value, we set to the nearest acceptable */
int dir = 0;
unsigned int exact_ivalue = audioSampleRate_;
if ((err = snd_pcm_hw_params_set_rate_near (pcm_handle, hwparams, &exact_ivalue, &dir) < 0)) {
_error("Alsa: Cannot set sample rate (%s)", snd_strerror (err));
return false;
} else
_debug ("Alsa: Set audio rate to %d", audioSampleRate_);
if (dir != 0) {
_error("Alsa: The chosen rate %d Hz is not supported by your hardware.Using %d Hz instead. ", audioSampleRate_, exact_ivalue);
//audioSampleRate_ = exact_ivalue;
// FIXME
}
/* Set the number of channels */
if ((err = snd_pcm_hw_params_set_channels (pcm_handle, hwparams, 1)) < 0) {
_debug ("Audio: Error: Cannot set channel count (%s)", snd_strerror (err));
return false;
}
/* Set the buffer size in frames */
unsigned long exact_lvalue = periodsize;
dir = 0;
if ((err = snd_pcm_hw_params_set_period_size_near (pcm_handle, hwparams, &exact_lvalue, &dir)) < 0) { snd_pcm_sw_params_t *swparams = NULL;
_debug ("Audio: Error: Cannot set period time (%s)", snd_strerror (err)); snd_pcm_sw_params_alloca(&swparams);
return false;
}
if (dir != 0)
_warn("Alsa: The chosen period size %lu bytes is not supported by your hardware.Using %lu instead. ", periodsize, exact_lvalue);
periodSize_ = exact_lvalue;
/* Set the number of fragments */
exact_ivalue = periods;
dir = 0;
if ((err = snd_pcm_hw_params_set_periods_near (pcm_handle, hwparams, &exact_ivalue, &dir)) < 0) {
_debug ("Audio: Error: Cannot set periods number (%s)", snd_strerror (err));
return false;
}
if (dir != 0)
_debug ("Audio: Warning: The chosen period number %i bytes is not supported by your hardware.Using %i instead. ", periods, exact_ivalue);
periods = exact_ivalue;
/* Set the hw parameters */
if ((err = snd_pcm_hw_params (pcm_handle, hwparams)) < 0) {
_debug ("Audio: Error: Cannot set hw parameters (%s)", snd_strerror (err));
return false;
}
snd_pcm_hw_params_free (hwparams);
/* Set the sw parameters */
snd_pcm_sw_params_malloc (&swparams);
snd_pcm_sw_params_current (pcm_handle, swparams);
/* Set the start threshold */
if ((err = snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams, periodSize_ * 2)) < 0) {
_debug ("Audio: Error: Cannot set start threshold (%s)", snd_strerror (err));
return false;
}
if ((err = snd_pcm_sw_params (pcm_handle, swparams)) < 0) { #define SW pcm_handle, swparams /* software parameters */
_debug ("Audio: Error: Cannot set sw parameters (%s)", snd_strerror (err)); snd_pcm_sw_params_current (SW);
return false; TRY(snd_pcm_sw_params_set_start_threshold (SW, periodSize * 2), "start threshold");
} TRY(snd_pcm_sw_params (SW), "sw parameters");
#undef SW
snd_pcm_sw_params_free (swparams);
return true; return true;
#undef TRY
} }
//TODO first frame causes broken pipe (underrun) because not enough data are send --> make the handle wait to be ready //TODO first frame causes broken pipe (underrun) because not enough data are send --> make the handle wait to be ready
......
...@@ -44,6 +44,9 @@ class AlsaThread; ...@@ -44,6 +44,9 @@ class AlsaThread;
* @brief Main sound class. Manages the data transfers between the application and the hardware. * @brief Main sound class. Manages the data transfers between the application and the hardware.
*/ */
/** Associate a sound card index to its string description */
typedef std::pair<int , std::string> HwIDPair;
class AlsaLayer : public AudioLayer class AlsaLayer : public AudioLayer
{ {
public: public:
...@@ -71,14 +74,6 @@ class AlsaLayer : public AudioLayer ...@@ -71,14 +74,6 @@ class AlsaLayer : public AudioLayer
*/ */
void stopStream (void); void stopStream (void);
/**
* Get data from the capture device
* @param buffer The buffer for data
* @param toCopy The number of bytes to get
* @return int The number of bytes acquired ( 0 if an error occured)
*/
int getMic (void * buffer, int toCopy);
/** /**
* Concatenate two strings. Used to build a valid pcm device name. * Concatenate two strings. Used to build a valid pcm device name.
* @param plugin the alsa PCM name * @param plugin the alsa PCM name
...@@ -116,14 +111,6 @@ class AlsaLayer : public AudioLayer ...@@ -116,14 +111,6 @@ class AlsaLayer : public AudioLayer
*/ */
int soundCardGetIndex (const std::string &description); int soundCardGetIndex (const std::string &description);
/**
* Get the current audio plugin.
* @return std::string The name of the audio plugin
*/
std::string getAudioPlugin (void) const {
return audioPlugin_;
}
void playback(int maxSamples); void playback(int maxSamples);
void capture(void); void capture(void);
...@@ -176,9 +163,6 @@ class AlsaLayer : public AudioLayer ...@@ -176,9 +163,6 @@ class AlsaLayer : public AudioLayer
*/ */
int indexRing_; int indexRing_;
/** Associate a sound card index to its string description */
typedef std::pair<int , std::string> HwIDPair;
// Copy Constructor // Copy Constructor
AlsaLayer (const AlsaLayer& rh); AlsaLayer (const AlsaLayer& rh);
...@@ -237,11 +221,6 @@ class AlsaLayer : public AudioLayer ...@@ -237,11 +221,6 @@ class AlsaLayer : public AudioLayer
*/ */
snd_pcm_t* captureHandle_; snd_pcm_t* captureHandle_;
/**
* Alsa parameter - Size of a period in the hardware ring buffer
*/
snd_pcm_uframes_t periodSize_;
/** /**
* name of the alsa audio plugin used * name of the alsa audio plugin used
*/ */
......
...@@ -157,7 +157,7 @@ class AudioLayer ...@@ -157,7 +157,7 @@ class AudioLayer
* Sample Rate SFLphone should send sound data to the sound card * Sample Rate SFLphone should send sound data to the sound card
* The value can be set in the user config file- now: 44100HZ * The value can be set in the user config file- now: 44100HZ
*/ */
const unsigned int audioSampleRate_; unsigned int audioSampleRate_;
/** /**
* Lock for the entire audio layer * Lock for the entire audio layer
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment