Simple Sound Controller
地味ですが・・・
一応ピッチの調整とパンの調整ができます。
2010.10.16 サウンドデータを更新しました。
※ 曲が長いのでローディングに時間がかかりそうです。(キャッシュしてしまえば速くなります)
/**
* Copyright mousepancyo ( http://wonderfl.net/user/mousepancyo )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/zBFj
*/
// forked from Event's Instrument
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.media.Sound;
import flash.net.URLRequest;
import flash.system.Security;
import com.bit101.components.*;
[SWF(width = 465,height = 465,frameRate = 30,backgroundColor = 0)]
public class Main extends Sprite{
private var _container:Sprite = new Sprite()
private var _sps:SoundPitchShift = new SoundPitchShift(_container, 465, 90);
private var _sound:Sound;
private var _upbtn:PushButton;
private var _downbtn:PushButton;
private var _pitchMeter:Meter;
private var _rbtn:PushButton;
private var _lbtn:PushButton;
private var _panMeter:Meter;
private var _rb1:RadioButton;
private var _rb2:RadioButton;
private var _rb3:RadioButton;
private var _rb4:RadioButton;
private var _label:Label;
public function Main() {
Security.allowDomain("*");
Security.loadPolicyFile("http://www.digifie.jp/crossdomain.xml");
//
graphics.beginFill(0);
graphics.drawRect(0, 0, 465, 465);
graphics.endFill()
//
_upbtn = new PushButton(this, 233, 250, "Pitch UP", null);
_downbtn = new PushButton(this, 131, 250, "Pitch DOWN", null);
_pitchMeter = new Meter(this, 132, 148, "Pitch Meter");
_pitchMeter.maximum = 2;
_pitchMeter.minimum = 0;
_pitchMeter.value = 1;
_pitchMeter.showValues = false
//
_rbtn = new PushButton(this, 233, 380, "Pan RIGHT", null);
_lbtn = new PushButton(this, 131, 380, "Pan LEFT", null);
_panMeter = new Meter(this, 132, 278, "Pan Meter");
_panMeter.maximum = 2;
_panMeter.value = 1;
_panMeter.showValues = false
//
_rb1 = new RadioButton(this, 50, 430, "Funk1", true, soundChange);
_rb2 = new RadioButton(this, 150, 430, "Reggae1", false, soundChange);
_rb3 = new RadioButton(this, 250, 430, "C&W1", false, soundChange);
_rb4 = new RadioButton(this, 350, 430, "Funk2", false, soundChange);
//
_label = new Label(this, 180, 80, "Loading Sound Data...");
_sound = new Sound(new URLRequest("http://www.digifie.jp/files/test3.mp3"));
_sound.addEventListener(Event.COMPLETE, soundLoadComp);
//
_upbtn.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
_upbtn.addEventListener(MouseEvent.MOUSE_UP, onUp);
_downbtn.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
_downbtn.addEventListener(MouseEvent.MOUSE_UP, onUp);
_rbtn.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
_rbtn.addEventListener(MouseEvent.MOUSE_UP, onUp);
_lbtn.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
_lbtn.addEventListener(MouseEvent.MOUSE_UP, onUp);
//
addChild(_container)
}
private function soundLoadComp(e:Event):void{
_sound.removeEventListener(Event.COMPLETE, soundLoadComp);
_sps.play(_sound);
_label.text = ""
}
// pitch shift
private function pitchUp(e:Event):void{
_sps.pitchShiftFactor += 0.01;
_pitchMeter.value = _sps.pitchShiftFactor;
if(_sps.pitchShiftFactor > 2) removeEventListener(Event.ENTER_FRAME, pitchUp);
}
private function pitchDown(e:Event):void{
_sps.pitchShiftFactor -= 0.01;
_pitchMeter.value = _sps.pitchShiftFactor;
if(_sps.pitchShiftFactor <= 0.5) removeEventListener(Event.ENTER_FRAME, pitchDown);
}
private function pitchRemoveDown(e:Event):void{
_sps.pitchShiftFactor -= 0.02;
if(_sps.pitchShiftFactor <= 1){
removeEventListener(Event.ENTER_FRAME, pitchRemoveDown);
_sps.pitchShiftFactor = 1;
}
_pitchMeter.value = _sps.pitchShiftFactor;
}
private function pitchRemoveUp(e:Event):void{
_sps.pitchShiftFactor += 0.02;
if(_sps.pitchShiftFactor >= 1){
removeEventListener(Event.ENTER_FRAME, pitchRemoveUp);
_sps.pitchShiftFactor = 1;
}
_pitchMeter.value = _sps.pitchShiftFactor;
}
// pan shift
private function panRight(e:Event):void{
_sps.panShiftFactor += 0.01;
_panMeter.value = 1 + _sps.panShiftFactor;
if(_sps.panShiftFactor >= 1) removeEventListener(Event.ENTER_FRAME, panRight);
}
private function panLeft(e:Event):void{
_sps.panShiftFactor -= 0.01;
_panMeter.value = 1 + _sps.panShiftFactor;
if(_sps.panShiftFactor <= -1) removeEventListener(Event.ENTER_FRAME, panLeft);
}
private function panRemoveLeft(e:Event):void{
_sps.panShiftFactor -= 0.02;
if(_sps.panShiftFactor <= 0){
removeEventListener(Event.ENTER_FRAME, panRemoveLeft);
_sps.panShiftFactor = 0;
}
_panMeter.value = 1 + _sps.panShiftFactor;
}
private function panRemoveRight(e:Event):void{
_sps.panShiftFactor += 0.02;
if(_sps.panShiftFactor >= 0){
removeEventListener(Event.ENTER_FRAME, panRemoveRight);
_sps.panShiftFactor = 0;
}
_panMeter.value = 1 + _sps.panShiftFactor;
}
// MouseEvent
private function onDown(e:MouseEvent):void{
switch(e.target as PushButton){
case _upbtn:
addEventListener(Event.ENTER_FRAME, pitchUp);
break;
case _downbtn:
addEventListener(Event.ENTER_FRAME, pitchDown);
break;
case _rbtn:
addEventListener(Event.ENTER_FRAME, panRight);
break;
case _lbtn:
addEventListener(Event.ENTER_FRAME, panLeft);
break;
}
}
private function onUp(e:MouseEvent):void{
switch(e.target as PushButton){
case _upbtn:
removeEventListener(Event.ENTER_FRAME, pitchUp);
addEventListener(Event.ENTER_FRAME, pitchRemoveDown);
break;
case _downbtn:
removeEventListener(Event.ENTER_FRAME, pitchDown);
addEventListener(Event.ENTER_FRAME, pitchRemoveUp);
break;
case _rbtn:
removeEventListener(Event.ENTER_FRAME, panRight);
addEventListener(Event.ENTER_FRAME, panRemoveLeft);
break;
case _lbtn:
removeEventListener(Event.ENTER_FRAME, panLeft);
addEventListener(Event.ENTER_FRAME, panRemoveRight);
break;
}
}
private function soundChange(e:Event):void{
_sps.stop()
_sound = null
_label.text = "Loading Sound Data..."
//
var bt:RadioButton = e.currentTarget as RadioButton
switch(bt.label){
case "Funk1":
_sound = new Sound(new URLRequest("http://www.digifie.jp/files/funk1.mp3"));
break;
case "Reggae1":
_sound = new Sound(new URLRequest("http://www.digifie.jp/files/reggae1.mp3"));
break;
case "C&W1":
_sound = new Sound(new URLRequest("http://www.digifie.jp/files/country1.mp3"));
break;
case "Funk2":
_sound = new Sound(new URLRequest("http://www.digifie.jp/files/funk2.mp3"));
break;
}
_sound.addEventListener(Event.COMPLETE, soundLoadComp);
}
}
}
//package {
import flash.display.Sprite;
import flash.media.*;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.SampleDataEvent;
import flash.utils.ByteArray;
class SoundPitchShift extends EventDispatcher {
private const CHANNEL_LENGTH:int = 256;
public var ch:SoundChannel;
public var srcBytes:ByteArray;
public var pitchShiftFactor:Number = 1;
public var panShiftFactor:Number = 0;
public var volShiftFactor:Number = 1;
public var position:Number;
private var _srcSound:Sound;
private var _plotHeight:int;
private var _waveWidthFactor:Number;
private var _waveBytes:ByteArray = new ByteArray();
private var _container:Sprite;
public function SoundPitchShift(container:Sprite, w:int, h:int) {
ch = new SoundChannel()
//
_container = container;
_waveWidthFactor = w / (CHANNEL_LENGTH * 2);
_plotHeight = h;
}
// play
public function play(src:Sound, pos:uint = 0):void {
this._srcSound = src;
position = pos;
//
var morphedSound:Sound = new Sound();
morphedSound.addEventListener(SampleDataEvent.SAMPLE_DATA, reSample);
ch = morphedSound.play();
ch.addEventListener(Event.SOUND_COMPLETE, soundComplete);
_container.graphics.clear();
}
// stop
public function stop():void {
ch.stop();
_container.graphics.clear();
}
// Event SoundComplete
private function soundComplete(event:Event):void {
dispatchEvent(event);
stop()
}
// Event reSample
private function reSample(event:SampleDataEvent):void {
var ba:ByteArray = new ByteArray();
position += _srcSound.extract(ba, 4096, position);
//
if (pitchShiftFactor>=1) {
event.data.writeBytes(shiftBytes(ba));//pitchShiftFactorが1かそれ以上の場合は音程を上げる
}else{
event.data.writeBytes(shiftBytesDown(ba));//pitchShiftFactorが1以下の場合は音程を下げる
}
//
if(panShiftFactor != 0){
ch.soundTransform = shiftPan()
}
//
if(volShiftFactor != 0.5){
ch.soundTransform = shiftVol()
}
//
waveGaneration()
}
// pitch UP
private function shiftBytes(ba:ByteArray):ByteArray {
var skipCount:Number=0;
var skipRate:Number;
var returnBa:ByteArray = new ByteArray();
skipRate = 1 + (1 / (pitchShiftFactor - 1));
ba.position=0;
while (ba.bytesAvailable > 0) {
skipCount++;
if (skipCount<=skipRate) {
returnBa.writeFloat(ba.readFloat());
returnBa.writeFloat(ba.readFloat());
} else {
ba.position+=8;
skipCount=skipCount-skipRate;
}
}
return returnBa;
}
// pitch DOWN
private function shiftBytesDown(ba:ByteArray):ByteArray {
var skipCount:Number=0;
var skipRate:Number;
var returnBa:ByteArray = new ByteArray();
skipRate = 1 + (1 / ((1+(1-pitchShiftFactor)) - 1));
ba.position=0;
while (ba.bytesAvailable > 0) {
skipCount++;
if (skipCount<=skipRate) {
returnBa.writeFloat(ba.readFloat());
returnBa.writeFloat(ba.readFloat());
} else {
ba.position-=8;
skipCount=skipCount-skipRate;
}
}
return returnBa;
}
// pan
private function shiftPan():SoundTransform {
var p_transform:SoundTransform = new SoundTransform(volShiftFactor,panShiftFactor)
return p_transform
}
// vol
private function shiftVol():SoundTransform {
var v_transform:SoundTransform = new SoundTransform(volShiftFactor,panShiftFactor)
return v_transform
}
// waveGanerator
private function waveGaneration():void {
SoundMixer.computeSpectrum(_waveBytes, false, 0);
//
_container.graphics.clear();
_container.graphics.lineStyle(0, 0x99FF00, 0.5);
_container.graphics.beginFill(0x99FF00,0.3);
_container.graphics.moveTo(0, _plotHeight);
//
var n:Number = 0;
// left channel
for (var i:int = 0; i < CHANNEL_LENGTH; i++) {
n = (_waveBytes.readFloat() * _plotHeight);
_container.graphics.lineTo(i * 2, _plotHeight - n);
}
_container.graphics.lineTo(CHANNEL_LENGTH * 2, _plotHeight);
_container.graphics.endFill();
// right channel
_container.graphics.lineStyle(0, 0xFF6600, 0.5);
_container.graphics.beginFill(0xFF6600, 0.3);
_container.graphics.moveTo(CHANNEL_LENGTH * 2, _plotHeight);
for (i = CHANNEL_LENGTH; i > 0; i--) {
n = (_waveBytes.readFloat() * _plotHeight);
_container.graphics.lineTo(i * 2, _plotHeight - n);
}
_container.graphics.lineTo(0, _plotHeight);
_container.graphics.endFill();
_container.scaleX = _waveWidthFactor
}
}
//}