0

私はオーディオ プログラミングの経験がなく、C++ は非常に低レベルの言語であるため、少し問題があります。http://www.steinberg.net/en/company/developers.htmlからダウンロードした ASIO SDK 2.3 を使用しています。

SDK内の例に基づいて独自のホストを作成しています。

今のところ、サンプル全体を確認できましたが、機能しているようです。PCに外部サウンドカードを接続しています。このデバイスのドライバーのロード、構成、コールバックの処理、アナログからデジタルへのデータのキャストなど、一般的なものに成功しました。

そして、私が今立ち往生している部分:デバイスを介してトラックを再生すると、ミキサー(デバイスのソフトウェア)でバーが動いているのが見えます。したがって、デバイスは正しい方法で接続されています。私のコードでは、ミキサーで移動しているバーの名前で入力と出力を選択しました。また、ASIOCreateBuffers() を使用して、各入力/出力のバッファーを作成しました。

  1. 間違っていたら訂正してください: ASIOStart() が呼び出され、ドライバーが実行状態にあるとき、サウンド信号を外部デバイスに入力すると、バッファーがデータでいっぱいになると思いますよね?

  2. ドキュメントを読んでいますが、少し迷っています - デバイスからアプリケーションに送信され、INPUT バッファに保存されているデータにアクセスするにはどうすればよいですか? それともシグナル?信号分析や将来の録音に必要です。

編集:複雑にした場合、一言で言えば、私の質問は次のとおりです:コードから入力ストリームデータにアクセスするにはどうすればよいですか? ドキュメントでそれを可能にするオブジェクト/コールバックが表示されません。

4

3 に答える 3

1

ASIO SDK のホスト サンプルは、必要なものにかなり近いものです。コールバックには、次のbufferSwitchTimeInfoようなコードがあります。

for (int i = 0; i < asioDriverInfo.inputBuffers + asioDriverInfo.outputBuffers; i++)
{
    int ch = asioDriverInfo.bufferInfos[i].channelNum;
    if (asioDriverInfo.bufferInfos[i].isInput == ASIOTrue)
    {
        char* buf = asioDriver.bufferInfos[i].buffers[index];
        ....

その内部の if ブロックasioDriver.bufferInfos[i].buffers[index]は生のオーディオ データへのポインタです (indexはメソッドへのパラメータです)。

バッファの形式はドライバに依存しており、テストによって検出できますasioDriverInfo.channelInfos[i].type。フォーマットのタイプは、32bit int LSB ファースト、32bit int MSB ファーストなどです。ASIOSampleTypeの列挙型で値のリストを見つけることができますasio.h。この時点で、サンプルを下流の信号処理コード用の一般的な形式に変換する必要があります。信号処理を行っている場合は、おそらく に変換する必要がありますdouble。このファイルhost\asioconvertsample.cppは、変換に何が含まれているかについてのアイデアを提供します。遭遇する最も一般的な形式は、おそらく INT32 MSB です。double に変換する方法は次のとおりです。

for (int i = 0; i < asioDriverInfo.inputBuffers + asioDriverInfo.outputBuffers; i++)
{
    int ch = asioDriverInfo.bufferInfos[i].channelNum;
    if (asioDriverInfo.bufferInfos[i].isInput == ASIOTrue)
    {
        switch (asioDriverInfo.channelInfos[i].type)
        {
            case ASIOInt32LSB:
            {
                double* pDoubleBuf = new double[_bufferSize];
                for (int i = 0 ; i < _bufferSize ; ++i)
                {
                    pDoubleBuf[i] = *(int*)asioDriverInfo.bufferInfos.buffers[index] / (double)0x7fffffff;
                }
                // now pDoubleBuf contains one channels worth of samples in the range of -1.0 to 1.0.
                break;
            }
            // and so on...
于 2015-01-09T06:34:38.530 に答える
0

どうもありがとうございました。あなたの答えはかなり役に立ちましたが、私はC++に少し慣れていないので、少し問題があると思います.

一般に、私は hostsample に基づいて独自のホストを作成しました。asioDriverInfo 構造体を実装せず、今のところ共通変数を使用します。

  1. 私の最初の問題は次のとおりです。

    char* buf = asioDriver.bufferInfos[i].buffers[index];
    

    (void*) を char* にキャストできないというエラーが発生しましたが、これでおそらく問題は解決しました。

    char* buf = static_cast<char*>(bufferInfos[i].buffers[doubleBufferIndex]);
    
  2. 私の 2 番目の問題は、データ変換に関するものです。あなたが私に勧めてくれたファイルをチェックしましたが、ちょっとした黒魔術だと思います。今のところ、私はあなたの例に従おうとしています:

    for (int i = 0; i < inputBuffers + outputBuffers; i++)
    {
        if (bufferInfos[i].isInput) 
        {
            switch (channelInfos[i].type)
            {
                case ASIOSTInt32LSB:
                {
                    double* pDoubleBuf = new double[buffSize];
                    for (int j = 0 ; j < buffSize ; ++j)
                    {
                        pDoubleBuf[j] = bufferInfos[i].buffers[doubleBufferIndex] / (double)0x7fffffff; 
                    }
                    break;
                }
            }
        } 
    

    そこでエラーが発生します:

    pDoubleBuf[j] = bufferInfos[i].buffers[doubleBufferIndex] / (double)0x7fffffff; 
    

    つまり:

    error C2296: '/' : illegal, left operand has type 'void *'
    

私が得られないのは、あなたの例にはそこにテーブルがないということです: asioDriverInfo.bufferInfos.buffers[index] の後に bufferInfos を修正しても...どのようなタイプにキャストして動作させる必要がありますか。P

PS。ASIOSTInt32LSB データ型は、私の PC では問題ないと確信しています。

于 2015-01-09T07:57:44.587 に答える