gpt4 book ai didi

actionscript-3 - 如何在ActionScript中播放WAV?

转载 作者:行者123 更新时间:2023-12-02 23:23:59 29 4
gpt4 key购买 nike

请参阅我在http://textsnip.com/see/WAVinAS3中创建的用于在ActionScript 3.0中解析WAVE文件的类。

此类正确地从文件头和fmt块中分离信息,隔离数据块,并创建一个新的ByteArray来存储数据块。它接收格式标签为1的未压缩WAVE文件。WAVE文件通过以下Flex嵌入标签嵌入到我的SWF中:

[Embed(source="some_sound.wav", mimeType="application/octet-stream")]
public var sound_class:Class;
public var wave:WaveFile = new WaveFile(new sound_class());

分离数据块之后,该类将尝试制作一个Sound对象,该对象可以从数据块中流式传输样本。我在流处理过程中遇到了问题,可能是因为我不擅长数学,并且真的不知道位/字节等发生了什么。

这是我用作WAVE文件格式引用的两个文档:
http://www.lightlink.com/tjweber/StripWav/Canon.html
https://ccrma.stanford.edu/courses/422/projects/WaveFormat/

现在,文件正在播放!实时甚至!但是...声音真的失真了。这是怎么回事?

最佳答案

问题出在onSampleData处理程序中。

在您的wav文件中,振幅存储为带符号的短裤,即16位整数。您正在将它们读为32位带符号的 float 。整数和浮点数在二进制文件中的表示方式有所不同,因此永远无法正常工作。

现在,玩家期望 float 。他们为什么使用浮子?不确定,但是一个很好的理由是它允许玩家接受每个样本的归一化值。这样,您就不必关心或知道播放器使用的是什么位数:最大值为1,最小值为-1,仅此而已。

因此,您的问题是必须将带符号的short转换为规范化的带符号浮点数。一个short占用16位,因此它可以存储2 ^ 16(或65,536)个不同的值。由于它是带符号的,所以符号占1位,因此最大值为2 ^15。因此,您知道输入的范围是-32,768 ... 32,767。

另一方面,样本值已标准化,并且必须在-1 ... 1的范围内。

因此,您必须规范化您的输入。这很容易。只需取读取值并将其除以最大值,即可将输入幅度转换为-1 ... 1.范围。

像这样:

    private function onSampleData(evt:SampleDataEvent):void 
{
var amplitude:int = 0;
var maxAmplitude:int = 1 << (bitsPerSample - 1); // or Math.pow(2, bitsPerSample - 1);
var sample:Number = 0;
var actualSamples:int = 8192;
var samplesPerChannel:int = actualSamples / channels;

for ( var c:int = 0; c < samplesPerChannel ; c++ ) {
var i:int = 0;
while(i < channels && data.bytesAvailable >= 2) {
amplitude = data.readShort();
sample = amplitude / maxAmplitude;
evt.data.writeFloat(sample);
i++;
}
}
}

需要注意的几件事:
  • maxAmplitude可以(可能
    应该)在您阅读时计算
    位深度。我在做
    方法只是为了您可以在
    粘贴的代码。
  • 虽然计算了maxAmplitude
    基于读取的位深,因此
    对于任何位深度都是正确的,
    我正在阅读短裤,所以
    如果您的wav文件碰巧使用了
    不同的位深,此功能
    将无法正常工作。你可以
    添加一个开关并阅读必要的内容
    数据量(即,如果为
    位深度是32)。但是,16位是
    如此广泛使用的标准
    怀疑这实际上是必需的。
  • 此功能适用于
    立体声波形。如果你想它工作
    对于单声道,请重新编写以编写
    同一样本两次。也就是说,对于每个
    阅读,您进行两次写(您的输入
    是单声道,但玩家期望2
    样本)。
  • 我尽可能地删除了EOF捕获
    知道您是否有足够的数据可读取
    从您的缓冲区检查
    bytesavailable。到达终点
    流在任何情况下都不异常(exception)
    IMO,所以我宁愿控制
    没有异常处理程序的情况下,
    但这只是个人的
    偏爱。
  • 关于actionscript-3 - 如何在ActionScript中播放WAV?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2933302/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com