瀏覽完聲音文檔後,似乎沒有辦法通過Actionscript 3.0來控制聲音的音高。只有控制音量和聲像的功能。爲什麼沒有音高屬性?這是在Actionscript中創建全功能聲音引擎的唯一缺陷嗎?使用Actionscript 3.0控制音高?
我希望我誤導了,但如果我不是有任何替代品/解決方法來控制AS3中的音高?
瀏覽完聲音文檔後,似乎沒有辦法通過Actionscript 3.0來控制聲音的音高。只有控制音量和聲像的功能。爲什麼沒有音高屬性?這是在Actionscript中創建全功能聲音引擎的唯一缺陷嗎?使用Actionscript 3.0控制音高?
我希望我誤導了,但如果我不是有任何替代品/解決方法來控制AS3中的音高?
Andre Michelle有很大article on Pitch控制使用ActionScript 3.0
供參考,在這裏是安德烈的示例代碼:
package components
{
import flash.events.Event;
import flash.events.SampleDataEvent;
import flash.media.Sound;
import flash.net.URLRequest;
import flash.utils.ByteArray;
/**
* @author Andre Michelle ([email protected])
*/
public class MP3Pitch
{
private const BLOCK_SIZE: int = 3072;
private var _mp3: Sound;
private var _sound: Sound;
private var _target: ByteArray;
private var _position: Number;
private var _rate: Number;
public function MP3Pitch(url: String)
{
_target = new ByteArray();
_mp3 = new Sound();
_mp3.addEventListener(Event.COMPLETE, complete);
_mp3.load(new URLRequest(url));
_position = 0.0;
_rate = 1.0;
_sound = new Sound();
_sound.addEventListener(SampleDataEvent.SAMPLE_DATA, sampleData);
}
public function get rate(): Number
{
return _rate;
}
public function set rate(value: Number): void
{
if(value < 0.0)
value = 0;
_rate = value;
}
private function complete(event: Event): void
{
_sound.play();
}
private function sampleData(event: SampleDataEvent): void
{
//-- REUSE INSTEAD OF RECREATION
_target.position = 0;
//-- SHORTCUT
var data: ByteArray = event.data;
var scaledBlockSize: Number = BLOCK_SIZE * _rate;
var positionInt: int = _position;
var alpha: Number = _position - positionInt;
var positionTargetNum: Number = alpha;
var positionTargetInt: int = -1;
//-- COMPUTE NUMBER OF SAMPLES NEED TO PROCESS BLOCK (+2 FOR INTERPOLATION)
var need: int = Math.ceil(scaledBlockSize) + 2;
//-- EXTRACT SAMPLES
var read: int = _mp3.extract(_target, need, positionInt);
var n: int = read == need ? BLOCK_SIZE : read/_rate;
var l0: Number;
var r0: Number;
var l1: Number;
var r1: Number;
for(var i: int = 0 ; i < n ; ++i)
{
//-- AVOID READING EQUAL SAMPLES, IF RATE < 1.0
if(int(positionTargetNum) != positionTargetInt)
{
positionTargetInt = positionTargetNum;
//-- SET TARGET READ POSITION
_target.position = positionTargetInt << 3;
//-- READ TWO STEREO SAMPLES FOR LINEAR INTERPOLATION
l0 = _target.readFloat();
r0 = _target.readFloat();
l1 = _target.readFloat();
r1 = _target.readFloat();
}
//-- WRITE INTERPOLATED AMPLITUDES INTO STREAM
data.writeFloat(l0 + alpha * (l1 - l0));
data.writeFloat(r0 + alpha * (r1 - r0));
//-- INCREASE TARGET POSITION
positionTargetNum += _rate;
//-- INCREASE FRACTION AND CLAMP BETWEEN 0 AND 1
alpha += _rate;
while(alpha >= 1.0) --alpha;
}
//-- FILL REST OF STREAM WITH ZEROs
if(i < BLOCK_SIZE)
{
while(i < BLOCK_SIZE)
{
data.writeFloat(0.0);
data.writeFloat(0.0);
++i;
}
}
//-- INCREASE SOUND POSITION
_position += scaledBlockSize;
}
}
}
基本用法是這樣的:
//create an MP3Pitch instance and load a sound
var mp3:MP3Pitch = new MP3Pitch("/path/to/your/file.mp3");
//change the pitch via rate setter
mp3.rate += 0.5
提取的ByteArray從聲音對象,然後操縱字節數據,返回一個新的字節陣列。
var sourceSnd:Sound = new Sound();
var outputSnd:Sound = new Sound();
var urlReq:URLRequest = new URLRequest("test.mp3");
sourceSnd.load(urlReq); sourceSnd.addEventListener(Event.COMPLETE, loaded);
function loaded(event:Event):void {
outputSnd.addEventListener(SampleDataEvent.SAMPLE_DATA, processSound);
outputSnd.play(); }
function processSound(event:SampleDataEvent):void {
var bytes:ByteArray = new ByteArray();
sourceSnd.extract(bytes, 4096);
event.data.writeBytes(upOctave(bytes)); }
function upOctave(bytes:ByteArray):ByteArray {
var returnBytes:ByteArray = new ByteArray();
bytes.position = 0;
while(bytes.bytesAvailable > 0)
{
returnBytes.writeFloat(bytes.readFloat());
returnBytes.writeFloat(bytes.readFloat());
if (bytes.bytesAvailable > 0)
{
bytes.position += 8;
}
}
return returnBytes;
}
驚人實際的例子!感謝您指點我! – TheDarkIn1978 2010-02-27 01:35:11
很高興它有幫助。最初,李Brimelow(http://theflashblog.com/?p=1129)有一個職位,但聲音是安德烈米歇爾的專業領域。 – 2010-02-27 02:37:53
-1因爲文章是斷開的鏈接。因此,我們看到至少把一些答案作爲「答案」的重要性,而不僅僅是鏈接。 – 2016-11-18 04:19:45