ALSA ( ) を使用して、3 バイトのサンプル アラインメントで 24 ビットの wav ファイルを再生しようとしていますlibasound.so.2
。また、ALSA はバッファー サイズの設定に失敗し、Invalid argument
エラーが発生します (ALSA はドライバーに何も渡しません)。
wav
ファイルヘッダーの内容は次のとおりです。
chunkId: 46464952
chunkSize: 221417340
format: "WAVE"
subchunk1Id: "fmt "
subchunk1Size: 40
audioFormat: fffe
numChannels: 2
sampleRate: 88200
byteRate: 529200
blockAlign: 6
bitsPerSample: 24
cbSize 16
wValidBitsPerSample 18
dwChannelMask 0
SubFormat
subchunk2Id: "data"
subchunk2Size: 221417280
残念ながら、クロスプラットフォーム プログラムの一部であり、個別にビルドできないため、適切なテスト プログラム ソースを提供できません。短い例は次のようになります
#include <stdio.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <semaphore.h>
#include "asoundlib.h"
int main(int argc, char *argv[])
{
int err = -1; /**< ALSA & clib function return code */
snd_pcm_t *p_handle = NULL; /**< pointer to active pcm object */
static const char *const p_device = "default"; /**< const pointer to const device id string */
unsigned int sampleRate = 0;
unsigned int rbuffertime = 0; /**< real buffer time as granted by ALSA */
err = snd_pcm_open(&p_handle, p_device, SND_PCM_STREAM_PLAYBACK, 0);
if (0 > err)
{
printf("Playback open error: %s\n", snd_strerror(err));
return err;
}
/* Get full range of possible hw params */
err = snd_pcm_hw_params_any(p_handle, p_hwparams);
if (0 > err)
{
printf("Error fetching hw param ranges: %s\n", snd_strerror(err));
return err;
}
// Specify a specific config out of configuration space and set it
err = snd_pcm_hw_params_set_rate_resample(p_handle, p_hwparams, 1);
if (0 > err)
{
printf("Unable to snd_pcm_hw_params_set_rate_resample for playback: %s\n", snd_strerror(err));
return err;
}
err = snd_pcm_hw_params_set_access(p_handle, p_hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
if (0 > err)
{
printf("Unable to snd_pcm_hw_params_set_access for playback: %s\n", snd_strerror(err));
return err;
}
err = snd_pcm_hw_params_set_format(p_handle, p_hwparams, SND_PCM_FORMAT_S24_3LE);
if (0 > err)
{
printf("Unable to snd_pcm_hw_params_set_format for playback: %s\n", snd_strerror(err));
return err;
}
err = snd_pcm_hw_params_set_channels(p_handle, p_hwparams, 2);
if (0 > err)
{
printf("Unable to snd_pcm_hw_params_set_channels for playback: %s\n", snd_strerror(err));
return err;
}
sampleRate = 88200;
err = snd_pcm_hw_params_set_rate_near(p_handle, p_hwparams, &sampleRate, 0);
if (0 > err)
{
printf("Unable to snd_pcm_hw_params_set_rate for playback: %s\n", snd_strerror(err));
return err;
}
rbuffertime = 500000;
err = snd_pcm_hw_params_set_buffer_time_near(p_handle, p_hwparams, &rbuffertime, 0);
if (0 > err)
{
printf("Unable to snd_pcm_hw_params_set_buffer_time_near for playback: %s\n", snd_strerror(err));
}
return err;
}
ALSA がsnd_pcm_hw_params_set_buffer_time_near()
呼び出し時にエラーで失敗する
ALSA ERROR hw_params: set_near (BUFFER_TIME)
value = 500000 : Invalid argument
ACCESS: RW_INTERLEAVED
FORMAT: S24_3LE
SUBFORMAT: STD
SAMPLE_BITS: 24
FRAME_BITS: 48
CHANNELS: 2
RATE: 88200
PERIOD_TIME: (476 247688)
PERIOD_SIZE: (42 21846)
PERIOD_BYTES: [256 131072]
PERIODS: [2 1024]
BUFFER_TIME: (495351 495352)
BUFFER_SIZE: 43690
BUFFER_BYTES: [262144 262140]
TICK_TIME: ALL
(ALSA はドライバにデータを渡そうとせず、セット バッファで失敗するだけです) そのプログラムは 16 ビット オーディオに適しています。
バッファのさまざまな値 (0.001 .. 1 秒) を試しましたが、どれも機能しません。3LE を使用する 24 ビットに必要な ALSA 構成の一部を見逃していたとします。以前の初期化ステップの結果のチェックでしょうか?
残念ながら、24 ビットでの ALSA の使用例を見つけることができません。例/推奨事項/ドキュメントへのリンクをアドバイスしていただければ幸いです。
編集済み
aplay
このファイルの結果は次のとおりです。
aplay -v /export/target/24bit_88.2kHz.wav
Playing WAVE '/export/target/24bit_88.2kHz.wav' : Signed 24 bit Little Endian in 3bytes, Rate 88200 Hz, Stereo
aplay: set_params:979: Sample format non available