2015-07-13 122 views
0

Im將麥克風數據採樣轉換爲16位PCM有符號整數存在問題。麥克風數據採樣

的應用程序,我已經是在Adobe AIR使用ActionScript 3,但我有使用網絡音頻API服務演示代碼,有它指出:

/** 
* Creates a Blob type: 'audio/l16' with the 
* chunk coming from the microphone. 
*/ 
var exportDataBuffer = function(buffer, bufferSize) { 
    var pcmEncodedBuffer = null, 
    dataView = null, 
    index = 0, 
    volume = 0x7FFF; //range from 0 to 0x7FFF to control the volume 

    pcmEncodedBuffer = new ArrayBuffer(bufferSize * 2); 
    dataView = new DataView(pcmEncodedBuffer); 

    /* Explanation for the math: The raw values captured from the Web Audio API are 
    * in 32-bit Floating Point, between -1 and 1 (per the specification). 
    * The values for 16-bit PCM range between -32768 and +32767 (16-bit signed integer). 
    * Multiply to control the volume of the output. We store in little endian. 
    */ 
    for (var i = 0; i < buffer.length; i++) { 
    dataView.setInt16(index, buffer[i] * volume, true); 
    index += 2; 
    } 

    // l16 is the MIME type for 16-bit PCM 
    return new Blob([dataView], { type: 'audio/l16' }); 
}; 

我需要一種方法來我的採樣轉換中同樣的方式。

這是我有,但它似乎並不奏效:

function micSampleDataHandler(event:SampleDataEvent):void 
    { 

     while(event.data.bytesAvailable) 
     { 
      var sample:Number = event.data.readFloat(); 
      var integer:int; 
      sample = sample * 32768 ; 
      if(sample > 32767) sample = 32767; 
      if(sample < -32768) sample = -32768; 
      integer = int(sample) ; 
      soundBytes.writeInt(integer); 
     } 

    } 

任何意見將幫助我一堆,感謝

編輯:

這是WaveEncoder功能我有。這可以被用於將樣品編碼成所需的格式:

public function encode(samples:ByteArray, channels:int=2, bits:int=16, rate:int=44100):ByteArray 
     { 
      var data:ByteArray = create(samples); 

      _bytes.length = 0; 
      _bytes.endian = Endian.LITTLE_ENDIAN; 

      _bytes.writeUTFBytes(WaveEncoder.RIFF); 
      _bytes.writeInt(uint(data.length + 44)); 
      _bytes.writeUTFBytes(WaveEncoder.WAVE); 
      _bytes.writeUTFBytes(WaveEncoder.FMT); 
      _bytes.writeInt(uint(16)); 
      _bytes.writeShort(uint(1)); 
      _bytes.writeShort(channels); 
      _bytes.writeInt(rate); 
      _bytes.writeInt(uint(rate * channels * (bits >> 3))); 
      _bytes.writeShort(uint(channels * (bits >> 3))); 
      _bytes.writeShort(bits); 
      _bytes.writeUTFBytes(WaveEncoder.DATA); 
      _bytes.writeInt(data.length); 
      _bytes.writeBytes(data); 
      _bytes.position = 0; 

      return _bytes; 
     } 

EDIT2:

問題似乎是:dataview.setInt16(byteOffset,值[,littleEndian])

我怎樣在as3中執行byteOffset?

+0

檢查您是否正在編寫雙聲道WAV而不是單聲道。如果是,則將該int寫入兩次,每個通道一次。同時檢查從bytearray sane中讀取的值(比如讀取浮點數時會產生兩個字節的偏移量會導致荒謬的值,而'readFloat()'不會爲您捕獲這個值)。 – Vesper

+0

我需要的結果是1channel。我檢查了readFloat()它總是返回一個介於-1和1之間的值:( – deloki

回答

0

明白了。 writeInt()寫入32位,而您只需要寫入16位。請改爲使用writeShort()

soundBytes.writeShort(integer); 
+0

謝謝,這絕對是我需要用來代替或writeInt的東西,但它仍然不起作用。仍然有東西似乎丟失了 – deloki

+0

也許有在設置'soundBytes'的頭文件時出現錯誤 – Vesper

+0

可以給我一些關於這個的更多信息嗎?你究竟是什麼意思?我不認爲我在任何地方設置標頭 – deloki