| |||||||
Du magst keine Werbung? Wir auch nicht!
Einfach registrieren und die Werbung ist weg. Diese Nachricht sehen nur nicht registrierte Nutzer.
![]() |
| | LinkBack | Themen-Optionen | Ansicht |
| | #1 (permalink) |
| [+] Registriert seit: Dec 2002 Ort: cologne
Beiträge: 2.271
| [PopForge Audio] Eine Sekunde Audio generieren
Nach der Konferenz bekomme ich diverse Anfragen, ob ich das Beispielscript, mit dem ich das Audio generiert habe veröffentlichen kann. Benötigt wird nur die PopForge Library. Ich beantworte gerne weitere Fragen hier. Code: package
{
import de.popforge.audio.output.Audio;
import de.popforge.audio.output.Sample;
import de.popforge.audio.output.SoundFactory;
import flash.display.Sprite;
import flash.media.Sound;
public class Main extends Sprite
{
public function Main()
{
init();
}
private function init(): void
{
var samples: Array = new Array();
var phase: Number = 0.0;
var frequence: Number = 440.0;
var sampleRate: Number = 44100.0;
var amplitude: Number;
var sample: Sample;
for( var i: int = 0 ; i < 44100 ; i++ ) //-- One second of audio
{
sample = samples[i] = new Sample();
amplitude = Math.sin( phase * Math.PI * 2.0 );
phase += frequence / sampleRate;
sample.left = sample.right = amplitude;
}
SoundFactory.fromArray( samples, Audio.STEREO, Audio.BIT16, Audio.RATE44100, onSoundCreated );
}
private function onSoundCreated( sound: Sound ): void
{
sound.play();
}
}
} |
| | |
| | #3 (permalink) |
| faulancer Registriert seit: Feb 2003
Beiträge: 281
|
Hi, toll, dass das framework jetzt opensource ist. ![]() Ich hab mal einen kleinen Test gemacht bei dem 2 wav files geladen werden. Dann werden die Samples von beiden Quellen ineinander kopiert. Hat mich überrascht, dass es auf anhieb funktioniert hat ![]() Jetzt quälen mich 2 Fragen: 1) wie kann ich als Quelle mp3s benutzen? 2) wie kann ich einen Endlos-Audiostream erzeugen und in diesen ständig neue Samples hinein-mergen? Mit der AudioBuffer Klasse hatte ich keinen Erfolg. Mein Ziel ist so ne Art Stepsequenzer. Code: package
{
import de.popforge.audio.output.Audio;
import de.popforge.audio.output.Sample;
import de.popforge.audio.output.SoundFactory;
import de.popforge.format.wav.WavFormat;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.media.Sound;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.utils.ByteArray;
import flash.utils.Timer;
public class SampleMerge
{
private var wavSamples:Array;
private var finalSamples:Array;
public function SampleMerge()
{
init();
}
private function init():void
{
wavSamples = [];
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, onLoad);
var request:URLRequest = new URLRequest("samples/drums_180224.wav");
loader.load(request);
var loader2:URLLoader = new URLLoader();
loader2.dataFormat = URLLoaderDataFormat.BINARY;
loader2.addEventListener(Event.COMPLETE, onLoad);
var request:URLRequest = new URLRequest("samples/scratch_720896.wav");
loader2.load(request);
}
private function onLoad(e:Event):void
{
var loader:URLLoader = URLLoader(e.target);
var b:ByteArray = loader.data;
var waveFormat:WavFormat = WavFormat.decode( b );
wavSamples.push( waveFormat.samples );
if (wavSamples.length == 2) mergeSamples();
}
private function mergeSamples():void
{
finalSamples = [];
for( var i: int = 0 ; i < wavSamples[0].length ; i++ )
{
finalSamples[i] = merge( wavSamples[0][i] , wavSamples[1][i] );
}
var timer:Timer = new Timer(500,1);
timer.addEventListener(TimerEvent.TIMER,generate);
timer.start();
}
private function merge(s1:Sample , s2:Sample ):Sample
{
return new Sample( (s1.left+s2.left) / 2 , (s1.right+s2.right) / 2 );
}
private function generate(e:Event):void
{
SoundFactory.fromArray( finalSamples , Audio.STEREO, Audio.BIT16, Audio.RATE44100, onSoundCreated );
}
private function onSoundCreated( sound: Sound ): void
{
sound.play(0,5);
}
}
} |
| | |
| | #4 (permalink) |
| \x3a\x6f\x29 Registriert seit: Apr 2004 Ort: paris
Beiträge: 806
|
Wärst du mal im Workshop gewesen Der Audiobuffer ist die richtige Wahl. Was hat denn nicht funktioniert?Vielleicht helfen dir die Synthesizer Sources aus dem Rent an idea Thread ja schon weiter. MP3: Geht nicht ohne die MP3 vorher zu decoden. Ich glaube das ist eine ganz schöne Arbeit. @agedoubleju: Hier wird genau eine Sekunde Audio synthetisiert. Wobei die Synthese sich auf eine einfache Sinuswelle beschränkt. |
| | |
| | #6 (permalink) | |
| Der Wunderhund Registriert seit: Jun 2002 Ort: Hattingen
Beiträge: 10.515
| Zitat:
![]() @André Michelle: Wie immer ein super Vortrag! Aber ich glaube die Vermieter der Räumlichkeiten haben ganz schön um ihre Boxen gebangt, als Du da die Sinuswellen durchgejagt hast. ![]() gruß, gaspode | |
| | |
| | #8 (permalink) |
| faulancer Registriert seit: Feb 2003
Beiträge: 281
|
danke für den Tipp mit dem Synthesizer - jetzt hats geklappt mit dem AudioBuffer. Das Problem war wohl, dass die Samples immer geklont werden müssen bevor sie an den Audio-Buffer gehen- ohne klonen werden alle nur genau 1x abgespielt, dann herrscht Stille. Hier der Code von meinem erfolgreichen Test: Code: package
{
import de.popforge.audio.output.Sample;
import de.popforge.audio.processor.IAudioProcessor;
import de.popforge.format.wav.WavFormat;
import flash.utils.ByteArray;
public class Synth implements IAudioProcessor
{
[Embed(source="samples/drums_180224.wav", mimeType="application/octet-stream")]
static private const Drums: Class;
[Embed(source="samples/piano_720896.wav", mimeType="application/octet-stream")]
static private const Piano: Class;
private var track1Samples:Array;
private var track2Samples:Array;
private var track1Position: int;
private var track2Position: int;
private var sampleCounter : int;
public function Synth()
{
init();
}
private function init(): void
{
sampleCounter = 0;
track1Position = 0;
track1Samples = getSamples( new Drums() );
track2Position = 0;
track2Samples = getSamples( new Piano() );
}
public function getSamples( wav:ByteArray ):Array
{
return WavFormat.decode( wav ).samples;
}
public function processAudio( samples: Array ): void
{
var s:Sample;
var mergeSamples:Array = [];
for( var i: int = 0 ; i < samples.length ; ++i )
{
mergeSamples = [];
s = Sample( track1Samples[track1Position] ).clone();
mergeSamples.push(s);
s = Sample( track2Samples[track2Position] ).clone();
mergeSamples.push(s);
samples[i] = mergeAll( mergeSamples );
track1Position++;
if (track1Position > track1Samples.length-1) track1Position = 0;
track2Position++;
if (track2Position > track2Samples.length-1) track2Position = 0;
sampleCounter++;
}
}
public function mergeAll( sa:Array ):Sample
{
var r:Number = 0;
var l:Number = 0;
for( var i: int = 0 ; i < sa.length ; ++i )
{
r += Sample( sa[i] ).right;
l += Sample( sa[i] ).left;
}
return new Sample(l,r);
}
public function reset():void
{
}
}
} ganz ISDN-freundlich |
| | |
| | #9 (permalink) | |
| [+] Registriert seit: Dec 2002 Ort: cologne
Beiträge: 2.271
| Zitat:
| |
| | |
| | #10 (permalink) |
| faulancer Registriert seit: Feb 2003
Beiträge: 281
|
mhh, stimmt bei mehreren "tracks" kann ich mir das clone() sparen, weil ich ja sowieso aus den benutzten Samples ein Neues generieren muss. Aber wie kann ich diesen Step optimieren? Ich muss ja die versch. Tracks zusammenbringen. Ich könnte mir halt vorstellen, dass ich z.b. den Buffer relativ lang mache. 30 Sekunden wären kein Problem. Bin da für Tipps dankbar |
| | |
| | #11 (permalink) | |
| [+] Registriert seit: Dec 2002 Ort: cologne
Beiträge: 2.271
| Zitat:
Benutzt du denn die Samples des AudioBuffers? | |
| | |
| | #12 (permalink) |
| faulancer Registriert seit: Feb 2003
Beiträge: 281
|
Ja, die Samples vom Buffer werden benutzt. Das ganze basiert ja auf eurem Synthesizer Code: Workshop: Rent an idea (Joa Ebert, Mario Klingemann und André Michelle) Ich hab das jetzt mal so optimiert, dass keine neuen Samples mehr erzeugt werden. Läuft rund soweit ![]() Auf jedenfall gefällt mir das so besser, als mit mehreren Soundobjekten gleichzeitig zu hantieren- zumal das Timing hier einfach viel sicherer ist. Audiobuffer ist ne feine Sache ![]() Code: package
{
import de.popforge.audio.output.Sample;
import de.popforge.audio.processor.IAudioProcessor;
import de.popforge.format.wav.WavFormat;
import flash.utils.ByteArray;
public class Synth implements IAudioProcessor
{
[Embed(source="samples/drums_180224.wav", mimeType="application/octet-stream")]
static private const Drums: Class;
[Embed(source="samples/piano_720896.wav", mimeType="application/octet-stream")]
static private const Piano: Class;
private var track1Samples:Array;
private var track2Samples:Array;
private var track1Position: int;
private var track2Position: int;
public function Synth()
{
init();
}
private function init(): void
{
track1Position = 0;
track1Samples = getSamples( new Drums() );
track2Position = 0;
track2Samples = getSamples( new Piano() );
}
public function getSamples( wav:ByteArray ):Array
{
return WavFormat.decode( wav ).samples;
}
public function processAudio( samples: Array ): void
{
var s:Sample;
var mergeSamples:Array;
for( var i: int = 0 ; i < samples.length ; ++i )
{
mergeSamples = [];
s = Sample( track1Samples[track1Position] );
mergeSamples.push(s);
s = Sample( track2Samples[track2Position] );
mergeSamples.push(s);
mergeAll( mergeSamples , samples[i] );
track1Position++;
if (track1Position > track1Samples.length-1) track1Position = 0;
track2Position++;
if (track2Position > track2Samples.length-1) track2Position = 0;
}
}
public function mergeAll( sa:Array , bufferSample:Sample ):void
{
var r:Number = 0;
var l:Number = 0;
for( var i: int = 0 ; i < sa.length ; ++i )
{
r += Sample( sa[i] ).right;
l += Sample( sa[i] ).left;
}
bufferSample.left = l;
bufferSample.right = r;
}
public function reset():void
{
}
}
} |
| | |
| | #13 (permalink) |
| faulancer Registriert seit: Feb 2003
Beiträge: 281
|
Da mir der Ansatz viel besser gefällt als mehrere Soundobjete parallel einzusetzen würde ich das gerne weiterverfolgen. Problem ist allerdings die Datenmenge die bei .wav Files aufkommt. Es gibt einen Java Mp3 Decoder - kann jemand einschätzen ob man den in AS3 einigermaßen performant hinbekommen kann ? Der Source ist recht umfangreich- wäre viel Aufwand den umzuschreiben. Kann man evtl. alternativ auch Sound-Assets aus swfs benutzen? Mit diesem Format sollte man doch leichter arbeiten können, oder? Hast du da schon Erfahrungswerte Andre? grüße |
| | |
| | #14 (permalink) |
| Neuer User Registriert seit: Feb 2007
Beiträge: 32
| Dauerton erzeugen
Hallo, ich habe mir mal die API von Andre angeschaut. Super. Was ich nun möchte: 1. wie kann ich einen dauerton einer bestimmten Frequenz erzeugen 2. diesem Ton durch eine pauser eine bestimmten länge unterbrechen sodass es ein dauerpiepen wird. Danke für hilfe Martin |
| | |
![]() |
| Lesezeichen |
| Themen-Optionen | |
| Ansicht | |
| |