私は現在、AM335xのMCASP1を使用するWM8776として組み込みボードを開発しています。これは期待どおりに機能し、予想される動作を持ちます。
今やりたいことは、周波数を切り替えることができるドライバを作ることです。クロックマルチプレクサを介してGPIOを介してMCASPに移動する2つのクロックがあります。このGPIOが高い場合、32/48/64/96/196などのオーディオでは24,576クロック、44.1/88.2/174などのオーディオでは11,960クロックがあります.
今私の目標は、カーネル空間で時計を変更できることです。これまでに私がしたことは、現在のサンプルレートを印刷するコードを入力することでした。すべて最高です。現在配信されているサンプルレートが表示されます。
ただし、.asoundrcでALSAリサンプリングを無効にすると、44.1khz(11,960mhz)クロックで96khzの曲を再生しようとすると、次のエラーが発生します。
alsa_open:303 unable to get period size: Invalid argument
このクロックでリサンプリングしないと、どのIntegerも完全なビットレートを達成できないため、これはもちろん論理的です。問題は、前述のカーネルに入れた印刷コメントに、現在のビットレートに関する情報が含まれていないことです。 ALSAはすでにこれを捉えていると思っているため、この機能には到達できません。
そのため、私はこのエラーの原因を追跡し、次のようにカーネルをプログラムできるように努めています。このビットレートで再生しているので、この特定のサウンドカードを使用するときに曲が変わるたびに変更したいと思います。この時計に。しかし、カーネルのサウンドコードを見ると、このエラーはどこにも見つかりません。
簡単に言えば、ユースケースは次のとおりです。
開始周波数は11.960Mhzです。 - >現在44.1Khzの曲を再生しています。 -> 96Khz曲に変更 -> GPIOを高く設定(クロックは現在24,512Mhz) ->時計が変更されたことをALSAおよびMCASPに通知します。
カーネル空間でMCASPを変更する方法を知っています。今私の質問は次のとおりです。
新しい再生が始まるたびに(曲の変更など)、最初の機能は何ですか?
このエラーの原因はどこにありますか?
私がしたいことをするより良い方法がありますか?
ベストアンサー1
2つあります。 PCM サンプル・ストリームを再生するアプリケーションと ALSA のカーネル側の間には、ユーザー空間 alsalib とオプションの内部リサンプリングがあります。アプリケーションがそれを無効にせずにデバイスをそのまま要求すると、カーネルは元の苗の割合が何であるかを知ることはできません。カーネルにはまったく表示されません。アプリケーションが純粋なハードウェアインターフェイスとしてALSAを使用せず、代わりにユーザースペースサウンドサーバー(Pulseaudio、Pipeline、esound、JACKなど)を使用している場合(ALSAデバイスのユーザースペース実装も提供し、次のことができます。) )内部的にミキシング/リサンプリング)状況はより正確です。これは最新のLinuxデスクトップの標準です。
アプリケーションがハードウェアを特定の速度でサンプリングしたい場合は、snd_pcm_hw_patams
alsalibから呼び出して、カーネルドライバに要求された速度を通知するために必要なシステムコールを実行します。何もしない最小限のプログラムを作成し、それを追跡してそれが何であるかを確認してください!
通常、複数のストリームを同時に、異なる速度で再生することが一般的であるため、ほとんどのアプリケーションではハードウェアパラメータ自体を操作しようとしないことが当然です。デバイスが正しく設定されるように要求し、通常は次のものが含まれます。選択したユーザー・スペース・パラメーター。