0

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
4

0 に答える 0