2013-03-27 9 views
5

QAudioOutputを使用して特定のサンプルレートでサンプルをサウンド出力デバイスに直接書き込む方法について質問があります。フレームごとにサウンドチップをエミュレートするエミュレータを作成し、オーディオ出力に書きたいフレームのオーディオサンプルを含むバッファを取得します。現在、私のオーディオ出力ルーチンをテストするために、私は巨大な(5分)を割り当てるので、同じように、に乱数を置くためにバッファ:Qt QAudioOutputプッシュモード

ヘッダー:

uint16_t *audio_outputBuffer; 
uint32_t audio_bytesRemainingToRead; 
QAudioOutput *audio_outputStream; 
QIODevice *audio_outputDevice; 

実装:

audio_outputBuffer = (uint16_t *) malloc((96000 * 4) * 300); 
int i = 0; 

uint16_t *tempAudioBuffer = audio_outputBuffer; 
for(i = 0; i < ((96000 * 4) * 150); i++) { 
    *tempAudioBuffer = (uint16_t) rand() & 0xFFFF; 
    tempAudioBuffer++; 
} 

audio_bytesRemainingToRead = (96000 * 4) * 300; 

次私はいくつかの基本的なパラメータで私のオーディオデバイスをセットアップしました:

// Set up the format 
QAudioFormat format; 
format.setFrequency(96000); // Usually this is specified through an UI option 
format.setChannels(2); 
format.setSampleSize(16); 
format.setCodec("audio/pcm"); 
format.setByteOrder(QAudioFormat::LittleEndian); 
format.setSampleType(QAudioFormat::UnSignedInt); 

// There's code here to notify the user of inability to match the format and choose an action, which is omitted for clarity 

// Create audio output stream, set up signals 
audio_outputStream = new QAudioOutput(format, this); 

connect(audio_outputStream, SIGNAL(stateChanged(QAudio::State)), this, SLOT(audio_stateChanged(QAudio::State))); 

audio_outputDevice = audio_outputStream->start(); 

次に、私のタイマーティックルーチン60 FPSでQTimerによって呼び出され、私はQAudioOutputのバッファにオーディオデータの「チャンク」を書くために、次のコードを実行します。

if(audio_outputDevice->isOpen() && audio_outputStream->state() != QAudio::StoppedState) { 
    qint64 bytesOfAudioWrittenToDevice = audio_outputDevice->write((char *) audio_outputBuffer, audio_outputStream->periodSize()); 
    audio_bytesRemainingToRead -= bytesOfAudioWrittenToDevice; 
    qDebug() << "Wrote" << bytesOfAudioWrittenToDevice << "bytes of audio to output device. Remaining bytes to read:" << audio_bytesRemainingToRead; 
    qDebug() << "Free bytes in audio output:" << audio_outputStream->bytesFree(); 
} 

私は、オーディオ出力処理を開始すると、私は、コンソール上で次の出力を得ます:QAudioOutputが、それは全体の事「は音が私のコンピュータから出てくるん」と一緒に行くサウンドカード、内部バッファのフラッシュしていないように私に

Current audio state: 3 Error: 0 
Wrote 2048 bytes of audio to output device. Remaining bytes to read: 115197952 
Free bytes in audio output: 6144 
Current audio state: 0 Error: 0 
Wrote 2048 bytes of audio to output device. Remaining bytes to read: 115195904 
Free bytes in audio output: 4096 
Wrote 2048 bytes of audio to output device. Remaining bytes to read: 115193856 
Free bytes in audio output: 2048 
Wrote 2048 bytes of audio to output device. Remaining bytes to read: 115191808 
Free bytes in audio output: 0 (This and the above line is repeated forever) 

、それが見えます。

この問題の原因とはどのように解決できますか?

(ちなみに、私は、Mac OS X 10.7.4上で、Qtの4.8.1に対する私のコードをコンパイルしています。)すべての答えを

感謝。

+0

一文に質問は何ですか?私は質問を読んだが、それを得ることはできなかった。 – sashoalm

+0

@sashoalm私は単純な1文の質問を反映するために投稿を改訂しました。うまくいけば分かりやすいでしょう。 –

答えて

7

アップフロントが指摘したいのは、これはではなく、 Qtバグです。どうして?答えは、WAVスペックでは、8ビットのサンプルは常に符号なしですが、16ビットのサンプルは常に符号付きです。それ以外の組み合わせは動作しません。これはデバイス関連のもので、フレームワークは何もできません。

16ビットのサンプルサイズと符号なし整数フォーマットを設定しているため、これは機能しません。 そして、はい、解決策は以下のとおりです。あなたが入れなければならないであろう8ビットのサンプルに対して逆

format.setSampleType(QAudioFormat::SignedInt); 

:あなたは16ビット分解能のために署名にサンプルタイプを設定する必要が

format.setSampleType(QAudioFormat:UnsignedInt); 

もこの同じような質問(同じ問題だが8ビット)は、Qtで符号付きまたは符号なしのサンプルを使用する際の特別な問題ではないことを示していますが、重要なサンプルサイズとタイプの組み合わせです(オーディオデバイス、 Qt用ではありません)QAudioOutput in Qt5 is not producing any sound

IMHO Qtが正しいフォーマットを強制することによってこれらのケースを処理するのを手伝っていないという事実は欠陥ですが、functionnalityの欠如はありません。

このページのノートセクションではこれについての詳細を学ぶことができます:https://ccrma.stanford.edu/courses/422/projects/WaveFormat/

1

私はこれを理解しました。明らかに、QtはUNSIGNEDサンプルに問題があります。サンプルの種類を署名に設定すると、プラットフォームに関係なくすべて正常に動作します。

関連する問題