麦克风数据采样
Microphone data sampling
我在将麦克风数据采样转换为 16 位 PCM 带符号整数时遇到问题。
我的应用程序是在带有 actionScript 3 的 Adobe AIR 中,但我有使用网络音频的服务演示代码 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;
}
编辑2:
问题似乎出在:dataview.setInt16(byteOffset, value [ littleEndian])
如何在 as3 中设置 byteOffset?
知道了。 writeInt()
写32位,你只需要写16位,用writeShort()
代替。
soundBytes.writeShort(integer);
我在将麦克风数据采样转换为 16 位 PCM 带符号整数时遇到问题。
我的应用程序是在带有 actionScript 3 的 Adobe AIR 中,但我有使用网络音频的服务演示代码 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;
}
编辑2:
问题似乎出在:dataview.setInt16(byteOffset, value [ littleEndian])
如何在 as3 中设置 byteOffset?
知道了。 writeInt()
写32位,你只需要写16位,用writeShort()
代替。
soundBytes.writeShort(integer);