2011-04-02 12 views
3

私が欲しいものを達成することができるかどうかはわかりませんが、基本的には録音を表すNSDictionaryがあります。これは、どの時点でどのサウンドIDが再生されたかのタイムラインです。OpenALを使用してiOSのサウンドのタイムラインからサウンドを書き出す方法

私はあなたがこのタイムライン/レコーディングを再生できるようにしており、完全に動作します。

このタイムラインを使用して、デバイスがiTunesと同期されている場合、コンピュータに保存できる単一のサウンドとしてエクスポートすることができますか?

基本的に私は、サウンドのタイムラインを取って再生し、これらのサウンドを単一のサウンドとして一緒にステッチしてエクスポートできるかどうかを尋ねています。

私はサウンドフレームワークとしてOpenALを使用しており、サウンドファイルはすべてCAFです。

ご迷惑をおかけして申し訳ございません。

ありがとうございます!

+0

これはできませんか? – c0dec0de

答えて

0

ファイルが単純な形式で保存されている場合、あまりにも難しくない方法は、それらを手動で組み合わせることです。つまり、caf形式の新しいファイルを作成し、必要な部分を手動でまとめます。

サウンドが非圧縮(リニアPCM)の場合、これは本当に簡単です。しかし、ここでCAFファイルフォーマットの文書を読む:

http://developer.apple.com/library/mac/#documentation/MusicAudio/Reference/CAFSpec/CAF_spec/CAF_spec.html#//apple_ref/doc/uid/TP40001862-CH210-SW1

+0

サウンドはIMA4を使用して圧縮されたCAFです。各個別のサウンドがいつ演奏されるのかを考慮した新しいCAFを作成することは可能でしょうか?その間に中断のない音のミッシュマッシュだけでなく、 – codeman

+0

これはもう少し作業です。このSOの質問にIMA4形式のデコードに関する情報があります:http://stackoverflow.com/questions/2130831/decoding-ima4-audio-format –

+0

デバイスのスピーカーから録音を再生することは可能でしょうか?これをAVAudioRecorderなどで録音してもらえますか? – codeman

1

はあなたが必要となります:リニアPCMオーディオ形式の

  • よく理解して(Wikipedia's Linear PCM pageを参照してください)。
  • タイミングをサンプルオフセットに変換するオーディオサンプルレートといくつかの基本的な数学についてよく理解しています。
  • two's-complement 2進数(符号付き/符号なし、16ビット、32ビットなど)がコンピュータに格納されていること、およびプロセッサのendian-nessがこれにどのように影響するかを認識しています。
  • 忍耐力、学習への興味、そしてこれを得る強い意欲。

はここで何をするかです:

  1. は(Info.plistの中UIFileSharingEnabled=YES/Documentsディレクトリにファイルを書き込む)のアプリでファイル共有を有効にします。

  2. リニアPCMオーディオデータを含むメモリバッファに使用済みサウンドをレンダリングします(まだない場合、つまり圧縮されている場合)。これは、オーディオキューのオフラインレンダリング機能を使用して行うことができます(Apple audio queue docs参照)。同じPCMフォーマットとサンプルレート(例えば16ビットの符号付きサンプル@ 44,100Hz)ですべてをレンダリングすると、ロットが簡単になり、すべてのサンプルでこのフォーマットを使用します。同じフォーマットを使用しますあなたの出力のために。モノフォーマットで始めてから、ステレオを追加することをお勧めします。

  3. は、非圧縮の出力形式を選択して、単一のストリームにあなたのサウンドをミックス:

    3.1。十分な大きさのバッファを割り当てるか、または書き込むファイルストリームを開きます。

    3.2。最初のサウンドが開始する前に、任意のヘッダーを書き出し(たとえば、未処理のPCMの代わりにWAV形式の出力を使用する場合)、ゼロを書き込んでください(または、サンプルサンプルフォーマットを使用しない場合はサンプル範囲の中間点)例えば、最初のサウンドの前に0.1秒の無音を望む場合は、4410(0.1 * 44100)のゼロサンプルを作成します。つまり、4410の短絡(16ビット)をゼロで書き込みます。

    3.3。今、すべての「現在再生中の」サウンドを追跡し、一緒にミックスします。現在再生中のサウンドの空のリストから始め、ミックスしているサンプルの「現在の時間」を追跡します。書き出すサンプルごとに、「現在の時間」をインクリメントするのは1.0/sample_rateです。別のサウンドが始まる時間が来たら、サンプルオフセットが0の '現在再生中の'リストに追加します。ミキシングを行うには、現在再生中のすべてのサウンドを繰り返し、現在のサンプルを追加します。それぞれのサンプルオフセットをインクリメントします。合計した値を出力バッファに書き込みます。たとえば、soundAが0.1秒(沈黙の後)で、soundBが0.2秒で開始する場合、サンプル8820の場合はoutput[8820] = soundA[4410] + soundB[0];、サンプル8821の場合はoutput[8821] = soundA[4411] + soundB[1];に相当します。サウンドが終了すると)現在再生中のリストから削除し、オーディオデータの最後まで続けます。

    3.4。上記の単純な混合(サンプルの合計)にはいくつかの問題があります。たとえば、2つのサンプルの値が32767より大きい値を持つ場合、符号付き16ビットの数値に格納することはできません。これはクリッピングと呼ばれます。今のところ、値を32767にクランプして動作させてください...後で戻って単純なリミッタを実装してください(最後の説明を参照)。

  4. あなたのトラックは非圧縮のリニアPCM形式で混在しているので、これで十分かもしれませんので、/Documentsに書き込んでください。圧縮形式で書き込む場合は、オーディオエンコーダのソースを取得し、リニアPCM出力を実行する必要があります。

シンプルリミッター:

絶対値が29490以上であるので、もし我々は値をスケールダウンします(int limitBegin = (int)(32767 * 0.9f);)、のは、サンプルの範囲の上位10%に制限することを選択しましょう。可能な最大のピークはint maxSampleValue = 32767 * numPlayingSounds;だろうと、私たちはそれでは、上記の非常にシンプルなミキサーごとにsampleValueへの加算を行う32767でピークにlimitBegin上記の値をスケールする:

if(sampleValue > limitBegin) 
{ 
    float overLimit = (sampleValue - limitBegin)/(float)(maxSampleValue - limitBegin); 
    sampleValue = limitBegin + (int)(overLimit * (32767 - limitBegin)); 
} 

あなたが注意を払っている場合numPlayingSoundsが変更されたとき(たとえば、新しいサウンドが開始されるときなど)、リミッターがより厳しい(またはそれ以下)になり、余分な音に対応するために突然音量が変更される可能性があります。代わりに最大数の再生音を使用するか、リミッターを数ミリ秒かけてランプアップさせるために賢明な方法を工夫することができます。

絶対値がsampleValue(符号付きの形式では負の場合もあります)で動作していることを覚えておいてください。サンプル範囲の両端(ピークとトラフ)の制限を処理するには、適切に記述する必要があります。また、ミキシング中に上記のすべてを最適化するためのいくつかのトリックがあります。ミキサーを書いている間にこれらを見つけることができます。注意して最初に働かせ、必要に応じてリファクタリング/最適化してください。

また、使用しているプラ​​ットフォームのエンディアンと書き込み先のファイル形式を考慮する必要があります。これは、一部のバイトスワッピングが必要な場合があるためです。

+0

'int maxSampleValue = 32767 * numPlayingSounds; 'を使用するとピークがうまくいっていません。実際にオーバーフローは防げますが、結合されたファイルの容量は制限をはるかに下回ります。より良い方法は、最初にソースオーディオファイルを(CDオーディオの通常の2バイト整数の代わりに)4バイト整数(または浮動小数点数)の配列に結合してから、実際のピーク値を見つけるために配列をスキャンし、次に、4バイトのオーディオを最終的な2バイト/サンプルの配列にスケールします。 – MusiGenesis

+0

これをすべて理解するにはしばらく時間がかかりますが、私は先に進み、あなたの答えが正しいと仮定します。 :) – codeman

+0

@MusiGenesisあなたが正しいと私が記述したリミッターは音量を少し下げますが、再生するサンプルの数に応じて90%を超えて蹴るだけです。ルックアヘッドでルックアヘッドを上げたり、カットイン値を変更したり、スケールダウン効果を上げて上端を丸めたりするなど、いくつかの改良を加えることができます。最も高いピークに基づいてすべてをスケーリングすることは、クリッピングを防止するもう1つの有効な方法ですが、コンプレッサーのようなローカルピークを先取りするランピングスケーラーを使用しない限り、全体の音量を低下させます。最初のシンプルなものを学ぶのがベストです:) – jhabbott

関連する問題