3

ユーザーが自分の声を録音してサーバーに送信する必要があるプロジェクトに取り組んでいます。ただし、送信する前に、ユーザーは録音したサウンドを再生する必要がある場合があります。

このアプリケーションには、SPEEX コーデックを使用した録音および再生機能があります。しかし、私が奇妙で難しいと感じたのは、ユーザーが録音したオーディオを再生すると、再生速度が通常より速くなったり遅くなったりして、理解できないことです。あたかも早送りのように。

サンプルコードは次のとおりです。

private var mic:Microphone;  
private var rec:ByteArray;  
private var snd:Sound;  
private var channel:SoundChannel; 

protected function recBtn_clickHandler(event:MouseEvent):void
{  

     rec = new ByteArray();
     mic = Microphone.getMicrophone();
     mic.setLoopBack(false);
     mic.setUseEchoSuppression(true);
     mic.gain = 50;
     mic.setSilenceLevel(5, 1000);
     mic.codec = SoundCodec.SPEEX;  

     mic.addEventListener(SampleDataEvent.SAMPLE_DATA, getMicAudio);  

}  

protected function plyBtn_clickHandler(event:MouseEvent):void
{  

     snd.addEventListener(SampleDataEvent.SAMPLE_DATA, playRecorded);  

     channel = snd.play();              
}     

private function getMicAudio(e:SampleDataEvent): void  
{

     rec.writeBytes(e.data);

}  

private function playRecorded(e:SampleDataEvent): void
{  

     if (!rec.bytesAvailable > 0) return;

     for (var i:int = 0; i < 2048; i++){
          var sample:Number = 0;  
          if (rec.bytesAvailable > 0) sample = rec.readFloat(); 

          for (var j:uint = 0; j < 6; j++) { 
               e.data.writeFloat(sample);
          }
     }  
}

このシナリオは、次の場合にのみ発生します。

  1. mic.codec = SoundCodec.SPEEX;
  2. マイクレート = 16

多くのフォーラムを調べましたが、SPEEX コーデックまたはマイクでマイクを再生するための解決策を見つけることができませんでした。rate = 16;

4

2 に答える 2

2

フラッシュでは、サウンド オブジェクトが 44khz で再生されます。16khz でサンプリングしているので、SampleDataEvent イベント ハンドラーを介してデータを 2.75 速く送信し、そのデータを取得しています。

つまり、2 回送信した場合です。

しかし、実際には、記録しているものよりも 3 倍速く書くことで、この問題を解決しようとしています。これはまだ最適ではありません。48 khz で録音されたかのようにデータを送信しているのに、44 khz で送信しているため、少しだけ遅くなったバージョンの録音が得られます。

あなたにできることは2つだけで、あなたはすでにそれらを実行していると思います。

そのforループで反復ごとに行う書き込みの数を調整します。または、最大増分 (2048) をより大きな数値に調整しますが、8192 を超えることはできないと思います。

Speexで録音したときも同じ問題がありました。

于 2011-06-06T22:41:32.450 に答える
1
e.data.writeFloat(sample);

e.data.writeFloat(sample);

e.data.writeFloat(sample);

e.data.writeFloat(sample);
if (i%3)
{
    e.data.writeFloat(sample);
    e.data.writeFloat(sample);
}
于 2011-06-21T00:48:01.447 に答える