-

   rss_rss_hh_full

 - e-mail

 

 -

 LiveInternet.ru:
: 17.03.2011
:
:
: 1

:


[] -

, 27 2017 . 13:11 +
PatientZero 13:11

-

image

, , -. , , MP3 WAV. , .

, . -, , . -, , .

ActionScript 3.0, , API .




( , ). , . .

, , .




.

MP3.

( -1.0 1.0), , n , , a , p :

var i:int = 0;
var n:int = 100;
var p:Number;

while( i < n ) {
    p = i / n;
    a[i] = p < 0.5 ? 1.0 : -1.0;
    i ++;
}




.

MP3.

( -1.0 1.0), n , , a , p :

var i:int = 0;
var n:int = 100;
var p:Number;

while( i < n ) {
    p = i / n;
    a[i] = p < 0.5 ? p * 2.0 : p * 2.0 - 2.0;
    i ++;
}





.

MP3.

( -1.0 1.0), , n , , a , p :

var i:int = 0;
var n:int = 100;
var p:Number;

while( i < n ) {
    p = i / n;
    a[i] = Math.sin( p * 2.0 * Math.PI );
    i ++;
}




.

MP3.

( -1.0 1.0), , n , , a , p :

var i:int = 0;
var n:int = 100;
var p:Number;

while( i < n ) {
    p = i / n;
    a[i] = p < 0.25 ? p * 4.0 : p < 0.75 ? 2.0 - p * 4.0 : p * 4.0 - 4.0;
    i ++;
}

6:

if (p < 0.25) {
    a[i] = p * 4.0;
}
else if (p < 0.75) {
    a[i] = 2.0 - (p * 4.0);
}
else {
    a[i] = (p * 4.0) - 4.0;
}




: , , . , , . (, Hz).

200- 0,5 20 :



, : 440 , (A4) . :

f = Math.pow( 2, n / 12 ) * 440.0;

n A4 . , (A5), A4, n 12, A5 12 A4. (E2), n -5, E2 5 A4. ( A4) :

n = Math.round( 12.0 * Math.log( f / 440.0 ) * Math.LOG2E );

, , .




, ( ) . , , 44100 44100 ( ) .

:



, . : , , ( ). : , .

, . () , . , ARGB . , 44100 705600 16- , :

bitsPerSample = bitRate / sampleRate;

, :

trace( 705600 / 44100 ); // "16"

, . .




, , , . , , (.. ).

. . , , 8 . , () .

.




, . (Flash): .

, . , ( ), .



AudioWaveform


- , .

noise, :

package noise {
	public final class AudioWaveform {
		static public const PULSE:int    = 0;
		static public const SAWTOOTH:int = 1;
		static public const SINE:int     = 2;
		static public const TRIANGLE:int = 3;
	}
}

, . true false .

static public function validate( waveform:int ):Boolean {
	if( waveform == PULSE    ) return true;
	if( waveform == SAWTOOTH ) return true;
	if( waveform == SINE     ) return true;
	if( waveform == TRIANGLE ) return true;
			
	return false;
}

, , . :

public function AudioWaveform() {
	throw new Error( "AudioWaveform class cannot be instantiated" );
}

.

enum, - , , . , , Java , ActionScript 3.0 .



Audio


Audio. ActionScript 3.0 Sound, Audio.

noise :

package noise {
	public class Audio {
		public function Audio() {}
	}
}

, , , . , , , . , /:

private var m_waveform:int     = AudioWaveform.PULSE;
private var m_frequency:Number = 100.0;
private var m_amplitude:Number = 0.5;
private var m_duration:Number  = 0.2;
private var m_release:Number   = 0.2;

, . amplitude 0.0 1.0, frequency , duration release .

, . /:

private var m_frequencyModulator:AudioModulator = null;
private var m_amplitudeModulator:AudioModulator = null;

, Audio , AudioEngine ( ). /:

internal var position:Number         = 0.0;
internal var playing:Boolean         = false;
internal var releasing:Boolean       = false;
internal var samples:Vector. = null;

position AudioEngine . . playing releasing AudioEngine, , samples , . , , AudioEngine.

Audio, /:

Audio.waveform

public final function get waveform():int {
	return m_waveform;
}
public final function set waveform( value:int ):void {
	if( AudioWaveform.isValid( value ) == false ) {
		return;
	}
	switch( value ) {
		case AudioWaveform.PULSE:    samples = AudioEngine.PULSE;    break;
		case AudioWaveform.SAWTOOTH: samples = AudioEngine.SAWTOOTH; break;
		case AudioWaveform.SINE:     samples = AudioEngine.SINE;     break;
		case AudioWaveform.TRIANGLE: samples = AudioEngine.TRIANGLE; break;
	}
	m_waveform = value;
}

Audio.frequency

[Inline]
public final function get frequency():Number {
	return m_frequency;
}
public final function set frequency( value:Number ):void {
	//  frequency  1.0 - 14080.0
	m_frequency = value < 1.0 ? 1.0 : value > 14080.0 ? 14080.0 : value;
}

Audio.amplitude

[Inline]
public final function get amplitude():Number {
	return m_amplitude;
}
public final function set amplitude( value:Number ):void {
	//  amplitude  0.0 - 1.0
	m_amplitude = value < 0.0 ? 0.0 : value > 1.0 ? 1.0 : value;
}

Audio.duration

[Inline]
public final function get duration():Number {
	return m_duration;
}
public final function set duration( value:Number ):void {
	//  duration  0.0 - 60.0
	m_duration = value < 0.0 ? 0.0 : value > 60.0 ? 60.0 : value;
}

Audio.release

[Inline]
public final function get release():Number {
	return m_release;
}
public function set release( value:Number ):void {
	//   release  0.0 - 10.0
	m_release = value < 0.0 ? 0.0 : value > 10.0 ? 10.0 : value;
}

Audio.frequencyModulator

[Inline]
public final function get frequencyModulator():AudioModulator {
	return m_frequencyModulator;
}
public final function set frequencyModulator( value:AudioModulator ):void {
	m_frequencyModulator = value;
}

Audio.amplitudeModulator

[Inline]
public final function get amplitudeModulator():AudioModulator {
	return m_amplitudeModulator;
}
public final function set amplitudeModulator( value:AudioModulator ):void {
	m_amplitudeModulator = value;
}

[Inline], . ActionScript 3.0 Compiler, , : () . , .



AudioModulator


AudioModulator Audio . Audio, , , , .

noise :

package noise {
	public class AudioModulator {
		public function AudioModulator() {}
	}
}

:

private var m_waveform:int            = AudioWaveform.SINE;
private var m_frequency:Number        = 4.0;
private var m_amplitude:Number        = 1.0;
private var m_shift:Number            = 0.0;
private var m_samples:Vector. = null;

, Audio, : , shift.

, shift, , (, , ) , . shift; 0.0 1.0, , . , , .

, , shift 0.0, , . shift 0.5, , .

, . AudioModulator , AudioEngine. :

[Inline]
internal final function process( time:Number ):Number {
	var p:int    = 0;
	var s:Number = 0.0;

	if( m_shift != 0.0 ) {
		time += ( 1.0 / m_frequency ) * m_shift;
	}

	p = ( 44100 * m_frequency * time ) % 44100;
	s = m_samples[p];

	return s * m_amplitude;
}

, , 44100 , ( ). , , .

AudioModulator, /:

AudioModulator.waveform

public function get waveform():int {
	return m_waveform;
}
public function set waveform( value:int ):void {
	if( AudioWaveform.isValid( value ) == false ) {
		return;
	}
	switch( value ) {
		case AudioWaveform.PULSE:    m_samples = AudioEngine.PULSE;    break;
		case AudioWaveform.SAWTOOTH: m_samples = AudioEngine.SAWTOOTH; break;
		case AudioWaveform.SINE:     m_samples = AudioEngine.SINE;     break;
		case AudioWaveform.TRIANGLE: m_samples = AudioEngine.TRIANGLE; break;
	}
	m_waveform = value;
}

AudioModulator.frequency

public function get frequency():Number {
	return m_frequency;
}
public function set frequency( value:Number ):void {
	//  frequency  0.01 - 100.0
	m_frequency = value < 0.01 ? 0.01 : value > 100.0 ? 100.0 : value;
}

AudioModulator.amplitude

public function get amplitude():Number {
	return m_amplitude;
}
public function set amplitude( value:Number ):void {
	//  amplitude  0.0 - 8000.0
	m_amplitude = value < 0.0 ? 0.0 : value > 8000.0 ? 8000.0 : value;
}

AudioModulator.shift

public function get shift():Number {
	return m_shift;
}
public function set shift( value:Number ):void {
	//  shift  0.0 - 1.0
	m_shift = value < 0.0 ? 0.0 : value > 1.0 ? 1.0 : value;
}

AudioModulator .



AudioEngine


: AudioEngine. . , Audio .

noise:

package noise {
	import flash.events.SampleDataEvent;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.utils.ByteArray;
	//
	public final class AudioEngine {
		public function AudioEngine() {
			throw new Error( "AudioEngine class cannot be instantiated" );
		}
	}
}

, , - , . final, .

, . , . 44 100 , . .

:

static internal const PULSE:Vector.    = new Vector.( 44100 );
static internal const SAWTOOTH:Vector. = new Vector.( 44100 );
static internal const SINE:Vector.     = new Vector.( 44100 );
static internal const TRIANGLE:Vector. = new Vector.( 44100 );

:

static private const BUFFER_SIZE:int    = 2048;
static private const SAMPLE_TIME:Number = 1.0 / 44100.0;

BUFFER_SIZE , API ActionScript 3.0 . , . , , . SAMPLE_TIME .

:

static private var m_position:Number            = 0.0;
static private var m_amplitude:Number           = 0.5;
static private var m_soundStream:Sound          = null;
static private var m_soundChannel:SoundChannel  = null;
static private var m_audioList:Vector.

  • m_position .
  • m_amplitude Audio.
  • m_soundStream m_soundChannel .
  • m_audioList Audio.
  • m_sampleList , , API ActionScript 3.0.

. , :

static private function $AudioEngine():void {
	var i:int    = 0;
	var n:int    = 44100;
	var p:Number = 0.0;
	//
	while( i < n ) {
		p = i / n;
		SINE[i] = Math.sin( Math.PI * 2.0 * p );
		PULSE[i] = p < 0.5 ? 1.0 : -1.0;
		SAWTOOTH[i] = p < 0.5 ? p * 2.0 : p * 2.0 - 2.0;
		TRIANGLE[i] = p < 0.25 ? p * 4.0 : p < 0.75 ? 2.0 - p * 4.0 : p * 4.0 - 4.0;
		i++;
	}
	//
	m_soundStream = new Sound();
	m_soundStream.addEventListener( SampleDataEvent.SAMPLE_DATA, onSampleData );
	m_soundChannel = m_soundStream.play();
}
$AudioEngine();

: , . , .

AudioEngine , Audio:

AudioEngine.play()

static public function play( audio:Audio ):void {
	if( audio.playing == false ) {
		m_audioList.push( audio );
	}
	//     ,     
	audio.position  = m_position - ( m_soundChannel.position * 0.001 );
	audio.playing   = true;
	audio.releasing = false;
}

AudioEngine.stop()

static public function stop( audio:Audio, allowRelease:Boolean = true ):void {
	if( audio.playing == false ) {
		//   
		return;
	}
	if( allowRelease ) {
		//        
		audio.position  = audio.duration;
		audio.releasing = true;
		return;
	}
	audio.playing   = false;
	audio.releasing = false;
}

AudioEngine.stopAll()

static public function stopAll( allowRelease:Boolean = true ):void {
	var i:int   = 0;
	var n:int   = m_audioList.length;
	var o:Audio = null;
	//
	if( allowRelease ) {
		while( i < n ) {
			o           = m_audioList[i];
			o.position  = o.duration;
			o.releasing = true;
			i++;
		}
		return;
	}
	while( i < n ) {
		o           = m_audioList[i];
		o.playing   = false;
		o.releasing = false;
		i++;
	}
}

, :

AudioEngine.onSampleData()

static private function onSampleData( event:SampleDataEvent ):void {
	var i:int       = 0;
	var n:int       = BUFFER_SIZE;
	var s:Number    = 0.0;
	var b:ByteArray = event.data;
	//
	if( m_soundChannel == null ) {
		while( i < n ) {
			b.writeFloat( 0.0 );
			b.writeFloat( 0.0 );
			i++;
		}
		return;
	}
	//
	generateSamples();
	//
	while( i < n ) {
		s = m_sampleList[i] * m_amplitude;
		b.writeFloat( s );
		b.writeFloat( s );
		m_sampleList[i] = 0.0;
		i++;
	}
	//
	m_position = m_soundChannel.position * 0.001;
}

, if , - m_soundChannel null. , SAMPLE_DATA m_soundStream.play() , SoundChannel.

while , m_soundStream ByteArray. :

AudioEngine.generateSamples()

static private function generateSamples():void {
	var i:int    = 0;
	var n:int    = m_audioList.length;
	var j:int    = 0;
	var k:int    = BUFFER_SIZE;
	var p:int    = 0;
	var f:Number = 0.0;
	var a:Number = 0.0;
	var s:Number = 0.0;
	var o:Audio  = null;
	//   audio
	while( i < n ) {
		o = m_audioList[i];
		//
		if( o.playing == false ) {
			//  audio  
			m_audioList.splice( i, 1 );
			n--;
			continue;
		}
		//
		j = 0;
		//     
		while( j < k ) {
			if( o.position < 0.0 ) {
				//  audio    
				o.position += SAMPLE_TIME;
				j++;
				continue;
			}
			if( o.position >= o.duration ) {
				if( o.position >= o.duration + o.release ) {
					//  audio 
					o.playing = false;
					j++;
					continue;
				}
				//  audio   
				o.releasing = true;
			}
			//      audio
			f = o.frequency;
			a = o.amplitude;
			//
			if( o.frequencyModulator != null ) {
				//  
				f += o.frequencyModulator.process( o.position );
			}
			//
			if( o.amplitudeModulator != null ) {
				//  
				a += o.amplitudeModulator.process( o.position );
			}
			//     
			p = ( 44100 * f * o.position ) % 44100;
			//   
			s = o.samples[p];
			//
			if( o.releasing ) {
				//     
				s *= 1.0 - ( ( o.position - o.duration ) / o.release );
			}
			//    
			m_sampleList[j] += s * a;
			//    audio
			o.position += SAMPLE_TIME;
			j++;
		}
		i++;
	}
}

, , , / m_amplitude:

static public function get amplitude():Number {
	return m_amplitude;
}
static public function set amplitude( value:Number ):void {
	//  amplitude  0.0 - 1.0
	m_amplitude = value < 0.0 ? 0.0 : value > 1.0 ? 1.0 : value;
}




. (Flash): .

, , , .



AudioProcessor


, :

package noise {
    public class AudioProcessor {
        //
        public var enabled:Boolean = true;

        //
        public function AudioProcessor() {
            if( Object(this).constructor == AudioProcessor ) {
                throw new Error( "AudioProcessor class must be extended" );
            }
        }

        //
        internal function process( samples:Vector. ):void {}
    }
}

, , process(), AudioEngine, , enabled, .



AudioDelay


AudioDelay , . AudioProcessor. , :

package noise {
    public class AudioDelay extends AudioProcessor {
        //
        public function AudioDelay( time:Number = 0.5 ) {
            this.time = time;
        }
    }
}

time, , ( ) , .

:

private var m_buffer:Vector. = new Vector.();
private var m_bufferSize:int  = 0;
private var m_bufferIndex:int = 0;
private var m_time:Number = 0.0;
private var m_gain:Number = 0.8;

m_buffer : , process, ( ) m_bufferIndex . , process().

m_bufferSize m_bufferIndex . m_time . m_gain , .

, process(), process() AudioProcessor:

internal override function process( samples:Vector. ):void {
    var i:int    = 0;
    var n:int    = samples.length;
    var v:Number = 0.0;
    //
    while( i < n ) {
        v  = m_buffer[m_bufferIndex]; //   
        v *= m_gain; //  
        v += samples[i]; //   
        //
        m_buffer[m_bufferIndex] = v;
        m_bufferIndex++;
        //
        if( m_bufferIndex == m_bufferSize ) {
            m_bufferIndex = 0;
        }
        //
        samples[i] = v;
        i++;
    }
}

, / m_time m_gain:

public function get time():Number {
    return m_time;
}
public function set time( value:Number ):void {
    //  time  0.0001 - 8.0
    value = value < 0.0001 ? 0.0001 : value > 8.0 ? 8.0 : value;
    //  time  ,     
    if( m_time == value ) {
        return;
    }
    //  time
    m_time = value;
    //   
    m_bufferSize    = Math.floor( 44100 * m_time );
    m_buffer.length = m_bufferSize;
}

public function get gain():Number {
    return m_gain;
}
public function set gain( value:Number ):void {
    //  gain  0.0 - 1.0
    m_gain = value < 0.0 ? 0.0 : value > 1.0 ? 1.0 : value;
}

, AudioDelay . , , ( m_buffer).



AudioEngine


, AudioEngine, . -, :

static private var m_processorList:Vector. = new Vector.();

AudioEngine, :

AudioEngine.addProcessor()

static public function addProcessor( processor:AudioProcessor ):void {
    if( m_processorList.indexOf( processor ) == -1 ) {
        m_processorList.push( processor );
    }
}

AudioEngine.removeProcessor()

static public function removeProcessor( processor:AudioProcessor ):void {
    var i:int = m_processorList.indexOf( processor );
    if( i != -1 ) {
        m_processorList.splice( i, 1 );
    }
}

AudioProcessor m_processorList.

, , , , process():

static private function processSamples():void {
    var i:int = 0;
    var n:int = m_processorList.length;
    //
    while( i < n ) {
        if( m_processorList[i].enabled ) {
            m_processorList[i].process( m_sampleList );
        }
        i++;
    }
}

, , onSampleData() AudioEngine:

if( m_soundChannel == null ) {
    while( i < n ) {
        b.writeFloat( 0.0 );
        b.writeFloat( 0.0 );
        i++;
    }
    return;
}
//
generateSamples();
processSamples();
//
while( i < n ) {
    s = m_sampleList[i] * m_amplitude;
    b.writeFloat( s );
    b.writeFloat( s );
    m_sampleList[i] = 0.0;
    i++;
}

processSamples();. processSamples(), .




, , . . , , .

, , . ( ), ( worker ActionScript 3.0), .

, . () , : , .

: , , . Ÿ , . .

, , - . , .

.

!
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/338544/

:  

: [1] []
 

:
: 

: ( )

:

  URL