1,
SampleRate,
(int)ceil(((double)SampleRate / 1000.0) * MinimumFrameDuration / 2),
- (int)ceil(((double)SampleRate / 1000.0) * MaximumFrameDuration * 2));
+ (int)ceil(((double)SampleRate / 1000.0) * MaximumFrameDuration));
snd_pcm_start(handle);
}
started = true;
if ( result == -EPIPE ) {
snd_pcm_recover(handle, result, 1);
- result = snd_pcm_readi(handle, array, length);
+ snd_pcm_start(handle);
std::cerr << "ALSA input \"" << parameters << "\": read underrun." << std::endl;
- if ( result == -EPIPE )
- return 0;
+ return 0;
}
if ( result >= 0 ) {
return result;
std::size_t
AudioInALSA::ready()
{
- static const int period_size = (int)ceil(
+ static const int min_frame_size = (int)ceil(
((double)SampleRate * 1000.0) * MinimumFrameDuration);
snd_pcm_sframes_t available = 0;
snd_pcm_sframes_t delay = 0;
int error;
- if ( !started )
- return period_size;
+ if ( !started ) {
+ snd_pcm_start(handle);
+ return min_frame_size;
+ }
error = snd_pcm_avail_delay(handle, &available, &delay);
if ( delay >= overlong_delay && available > 0 ) {
snd_pcm_drop(handle);
snd_pcm_prepare(handle);
- started = false;
+ snd_pcm_start(handle);
const double seconds = (double)delay / (double)SampleRate;
error = snd_pcm_avail_delay(handle, &available, &delay);
std::cerr << "ALSA input \"" << parameters << "\": overlong delay, dropped "
- << seconds << " seconds of queued audio samples." << std::endl;
+ << seconds << " seconds of input." << std::endl;
- return 0;
+ return min_frame_size / 2;
}
if ( error == -EPIPE ) {
private:
char * const parameters;
snd_pcm_t * handle;
- std::size_t period_size;
+ std::size_t min_frame_size;
bool started;
void
AudioOutALSA::AudioOutALSA(const char * p)
: AudioOutput("alsa", p), parameters(strdup(p)),
- period_size(
+ min_frame_size(
(int)ceil(((double)SampleRate / 1000.0) * MinimumFrameDuration)),
started(false)
{
SND_PCM_ACCESS_RW_INTERLEAVED,
1,
SampleRate,
- period_size / 2,
- (int)ceil(((double)SampleRate / 1000.0) * MaximumFrameDuration));
+ min_frame_size / 2,
+ min_frame_size * 8);
+ snd_pcm_pause(handle, 1);
}
AudioOutALSA::~AudioOutALSA()
int error;
if ( !started )
- return period_size * 2;
+ return min_frame_size;
error = snd_pcm_avail_delay(handle, &available, &delay);
+ if ( delay > (((double)SampleRate / 1000.0) * MaximumFrameDuration) ) {
+ const double seconds = (double)delay / (double)SampleRate;
+
+ std::cerr << "ALSA output \"" << parameters
+ << "\": overlong delay, dropped "
+ << seconds << " seconds of output." << std::endl;
+ snd_pcm_drop(handle);
+ snd_pcm_prepare(handle);
+ started = false;
+ return 0;
+ }
if ( error == -EPIPE ) {
std::cerr << "ALSA output \"" << parameters << "\": ready underrun." << std::endl;
snd_pcm_recover(handle, error, 1);
snd_pcm_pause(handle, 1);
started = false;
- return (int)ceil(((double)SampleRate / 1000.0) * MinimumFrameDuration);
+ return min_frame_size;
if ( error < 0 )
return 0;