我遇到了将麦克风数据采样转换为16位PCM有符号整数的问题。
我的应用程序位于Adobe AIR中,带有actionScript 3,但我有使用Web Audio 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,value [,littleEndian])
我如何在as3中执行byteOffset?
答案 0 :(得分:0)
知道了。 writeInt()
写入32位,您只需要写入16.请改用writeShort()
。
soundBytes.writeShort(integer);