Alsa constructor
Play buffer of audio
Implementation
Alsa(
this.rate,
this.channels,
) {
// https://github.com/dart-lang/ffigen/issues/72#issuecomment-672060509
final name = 'default'.toNativeUtf8().cast<Int8>();
final stream = 0;
// 0 ia "standard blocking mode";
// final mode = 0;
final mode = a.SND_PCM_NONBLOCK;
final ratePtr = calloc<Uint32>();
ratePtr.value = rate;
final dirPtr = Pointer<Int32>.fromAddress(0);
final tmpPtr = calloc<Uint32>();
framesPtr = calloc<Uint64>();
/* Open the PCM device in playback mode */
final openResult = alsa.snd_pcm_open(pcmHandlePtr, name, stream, mode);
if (openResult < 0) {
final errMesg = alsa.snd_strerror(openResult).cast<Utf8>().toDartString();
throw Exception('ERROR: Can\`t open $name PCM device: $errMesg');
}
var paramsPtr = calloc<Pointer<a.snd_pcm_hw_params_>>();
// Allocate parameters object
alsa.snd_pcm_hw_params_malloc(paramsPtr);
alsa.snd_pcm_hw_params_any(pcmHandlePtr.value, paramsPtr.value);
/* Set parameters */
var result = 0;
result = alsa.snd_pcm_hw_params_set_access(pcmHandlePtr.value,
paramsPtr.value, a.snd_pcm_access_t.SND_PCM_ACCESS_RW_INTERLEAVED);
if (result < 0) {
throw Exception("ERROR: Can't set interleaved mode.");
}
result = alsa.snd_pcm_hw_params_set_format(pcmHandlePtr.value,
paramsPtr.value, a.snd_pcm_format_t.SND_PCM_FORMAT_S16_LE);
if (result < 0) {
throw Exception("ERROR: Can't set playback format.");
}
result = alsa.snd_pcm_hw_params_set_channels(
pcmHandlePtr.value, paramsPtr.value, channels);
if (result < 0) {
throw Exception("ERROR: Can't set number of channels.");
}
result = alsa.snd_pcm_hw_params_set_rate_near(
pcmHandlePtr.value, paramsPtr.value, ratePtr, dirPtr);
if (result < 0) {
throw Exception("ERROR: Can't set playback rate.");
}
/* Write parameters */
result = alsa.snd_pcm_hw_params(pcmHandlePtr.value, paramsPtr.value);
if (result < 0) {
throw Exception(
"ERROR: Can't set hardware parameters. ${alsa.snd_strerror(result).cast<Utf8>().toDartString()}");
}
/* Resume information */
final pcmName =
(alsa.snd_pcm_name(pcmHandlePtr.value)).cast<Utf8>().toDartString();
_printDebug('PCM name: $pcmName');
_printDebug(
'PCM state: ${alsa.snd_pcm_state_name(alsa.snd_pcm_state(pcmHandlePtr.value)).cast<Utf8>().toDartString()}');
alsa.snd_pcm_hw_params_get_channels(paramsPtr.value, tmpPtr);
var channelType;
if (tmpPtr.value == 1) {
channelType = '(mono)';
} else if (tmpPtr.value == 2) {
channelType = '(stereo)';
}
_printDebug('channels: ${tmpPtr.value} $channelType');
alsa.snd_pcm_hw_params_get_rate(paramsPtr.value, tmpPtr, dirPtr);
_printDebug('rate: ${tmpPtr.value} bps');
/* Allocate buffer to hold single period */
alsa.snd_pcm_hw_params_get_period_size(paramsPtr.value, framesPtr, dirPtr);
_printDebug('period size: ${framesPtr.value}');
buff_size = framesPtr.value * channels * 2 /* 2 -> sample size */;
_printDebug('set buffer size: $buff_size');
alsa.snd_pcm_hw_params_get_period_time(paramsPtr.value, tmpPtr, dirPtr);
_printDebug('time period: ${tmpPtr.value}');
audioFramesBuffer = calloc<Uint8>(buff_size);
calloc.free(paramsPtr);
calloc.free(ratePtr);
calloc.free(dirPtr);
}