[alsa-devel] Basic questions
tsepp2001 at t-online.de
tsepp2001 at t-online.de
Sun Jul 30 12:00:04 CEST 2017
Hi everybody,
I am new to ALSA-API and would be glad, if someone give me an advice to
the following questions. Up to now I used Rtaudio for cross compiling
the player for windows and Linux. But know I need to go more into ALSA...
- Am I right to use async mode to get lowest latency times and using
pause/play/stop?
- I used the following piece of code. But don't get any output. The
callback output shows "avail" with very short count of frames...
I write a whole file (raw) to buffer, called buffer_alsa with 6894888
frames. What is going wrong?
I get this output:
Frames: 6894888
buffer_size (frames): 2048
buffer_time (frames): 46439
period_size (frames): 256
period_time (usec): 5804
periods (count): 8
Avail: 1540
Avail: 1285
Avail: 1030
Avail: 775
Avail: 520
Avail: 265
Avail: 10
Avail: 2
Avail: 2
Avail: 3
Avail: 2
...
The code follows ...
Best regards
Thomas
-----------------------------
void MyCallback(snd_async_handler_t *pcm_callback)
{
snd_pcm_t *handle = snd_async_handler_get_pcm(pcm_callback);
snd_pcm_sframes_t avail;
//std::cout << "Period_size: " << period_size << std::endl;
avail = snd_pcm_avail_update(handle);
while (avail >= period_size)
{
snd_pcm_writei(handle, buffer_alsa , period_size);
avail = snd_pcm_avail_update(handle);
std::cout << " Avail: " << avail << std::endl;
}
}
//----------------------------------------------------
snd_pcm_hw_params_alloca(¶ms);
if ((err = snd_pcm_hw_params_any(handle, params)) < 0)
std::cout << " Error (reading configuration): " <<
snd_strerror(err) << std::endl;
/* Set parameters */
if ((err = snd_pcm_hw_params_set_access(handle,
params,SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
//printf("ERROR: Can't set interleaved mode. %s\n", snd_strerror(err));
std::cout << " Error (can't set interleaved mode): " <<
snd_strerror(err) << std::endl;
if ((err = snd_pcm_hw_params_set_format(handle, params, FORMAT)) < 0)
//printf("ERROR: Can't set format. %s\n", snd_strerror(err));
std::cout << " Error (can't set format): " <<
snd_strerror(err) << std::endl;
if ((err = snd_pcm_hw_params_set_channels(handle, params,
data.channels)) < 0)
//printf("ERROR: Can't set channels number. %s\n", snd_strerror(err));
std::cout << " Error (can't set channels number): " <<
snd_strerror(err) << std::endl;
if ((err = snd_pcm_hw_params_set_rate_near(handle, params, &fs, 0)) < 0)
//printf("ERROR: Can't set rate. %s\n", snd_strerror(err));
std::cout << " Error (can't set rate): " <<
snd_strerror(err) << std::endl;
if ((err = snd_pcm_hw_params_set_buffer_size_near(handle, params,
&buffer_size)) < 0)
std::cout << " Error (can't set buffer size): " <<
snd_strerror(err) << std::endl;
if ((err = snd_pcm_hw_params_set_period_size_near (handle, params,
&period_size, NULL)) < 0)
std::cout << " Error (can't set period size): " <<
snd_strerror(err) << std::endl;
/* Write parameters */
if ((err = snd_pcm_hw_params(handle, params)) < 0)
//printf("ERROR: Can't set hardware parameters. %s\n", snd_strerror(err));
std::cout << " Error (can't set harware params): " <<
snd_strerror(err) << std::endl;
//---------------------- ------------------------------
// Get Parameters
snd_pcm_hw_params_get_buffer_size(params, &buffer_sz);
std::cout << " buffer_size (frames): " << buffer_sz <<
std::endl;
snd_pcm_hw_params_get_buffer_time(params, &buffer_tm, NULL);
std::cout << " buffer_time (frames): " << buffer_tm <<
std::endl;
snd_pcm_hw_params_get_period_size(params, &aframes, 0);
std::cout << " period_size (frames): " << aframes <<
std::endl;
snd_pcm_hw_params_get_period_time(params, &data.channels, NULL); // tmp
Zeit in us
std::cout << " period_time (usec): " << data.channels
<< std::endl;
snd_pcm_hw_params_get_periods(params, &piods, 0);
std::cout << " periods (count): " << piods << std::endl;
//
----------------------------------------------------------------------------
//snd_pcm_hw_params_free (params);
// --------------------- Hardware-Params End ------------------------------
snd_pcm_sw_params_t *sw_params;
if ((err = snd_pcm_sw_params_malloc (&sw_params)) < 0)
{
std::cout << " Error (can't allocate sw params): " <<
snd_strerror(err) << std::endl;
return;
}
if ((err = snd_pcm_sw_params_current(handle, sw_params)) < 0)
{
std::cout << "Error (can't return curr sw config): " <<
snd_strerror(err) << std::endl;
return;
}
if ((err = snd_pcm_sw_params_set_start_threshold (handle, sw_params,
buffer_size)) < 0) // 0U oder 4096 ?
{ // This parameter controls the wake up point. If the count of
available samples is equal or greater than this value, then the
application will be activated.
std::cout << "Error (can't set start thresh mode): " <<
snd_strerror(err) << std::endl;
return;
}
/*
if ((err = snd_pcm_sw_params_set_silence_threshold( handle, sw_params, 0
)) < 0)
{
std::cout << " Error (can't set silence thres): " <<
snd_strerror(err) << std::endl;
return;
}
*/
if ((err = snd_pcm_sw_params_set_avail_min (handle, sw_params,
period_size)) < 0)
{
std::cout << " Error (can't set min avail count): " <<
snd_strerror(err) << std::endl;
return;
}
// here are two options for a fix
//snd_pcm_sw_params_set_silence_size( phandle, sw_params, ULONG_MAX );
/*
snd_pcm_uframes_t val;
if ((err = snd_pcm_sw_params_get_boundary(sw_params, &val)) < 0)
{
std::cout << " Error (can't get boundary): " <<
snd_strerror(err) << std::endl;
return;
}
if ((err = snd_pcm_sw_params_set_silence_size(handle, sw_params, val)) < 0)
{
std::cout << " Error (can't set silence): " <<
snd_strerror(err) << std::endl;
return;
}
*/
if ((err = snd_pcm_sw_params(handle, sw_params)) < 0)
{
std::cout << " Error (can't set sw params): " <<
snd_strerror(err) << std::endl;
return;
}
snd_pcm_sw_params_free(sw_params);
// ------------------------- SW-Params End ---------------------------------
if ((err = snd_pcm_prepare(handle)) < 0)
{
std::cout << " Error (can't prepare audio): " <<
snd_strerror(err) << std::endl;
return;
}
snd_async_handler_t *pcm_callback;
if ((err = snd_async_add_pcm_handler(&pcm_callback, handle, MyCallback,
NULL)) < 0)
{
std::cout << " Error (can't add pcm handler): " <<
snd_strerror(err) << std::endl;
return;
}
if ((err = snd_pcm_writei(handle, buffer_alsa, 2 * period_size) == -EPIPE))
{
std::cout << " Error: XRUN" << std::endl;
err = snd_pcm_recover(handle, err, 0);
if ((err = snd_pcm_prepare (handle)) < 0)
{
std::cout << " Error (can't prepare audio): " <<
snd_strerror(err) << std::endl;
return;
}
}
if ((err = snd_pcm_start(handle)) < 0)
{
std::cout << " Error (can't start audio): " <<
snd_strerror(err) << std::endl;
return;
}
void MyCallback(snd_async_handler_t *pcm_callback);
More information about the Alsa-devel
mailing list