| |||||||
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) |
| Neuer User Registriert seit: Nov 2008
Beiträge: 14
| ByteArray zu Sound?
Ich seh grad nicht wie, aber ist es möglich aus einem ByteArray oder genauer einen schon geladenen Datenblock in ein Soundobjekt umzuwandeln? Hintergrund: Ich möchte gerne gepackte Resourcen (also als ZIP) nachladen, darunter auch Sounddateien. Nun habe ich nach Laden nur die reinen Daten. Gibt es einen Weg daraus ein Sound-Objekt zu machen ?MfG Lotes |
| | |
| | #4 (permalink) |
| Neuer User Registriert seit: Nov 2008
Beiträge: 14
|
So hab's mir angeschaut :-). Da haste ganz clever ne SWF-Datei Byte für Byte samt Sounddaten geschrieben und geladen. Ich hab ein bissel recherchiert. Gute Links zum Dateiaufbau einer SWF sind: http://www.swfmill.org/ http://www.half-serious.com/swf/format/index.html Ich werd mir jetzt nen Fetzen AS3 zusammenklappern, der mir MP3-Daten zu Sound lädt. Bei Erfolg poste ich den Code-Schnipsel hier rein :-). |
| | |
| | #5 (permalink) |
| Neuer User Registriert seit: Nov 2008
Beiträge: 14
|
So fertig. Der Code ist stark angelehnt an Popforge. Folgende Datei ist davon entwendet ;-): swf.bin Sie ist ein Teil der SWF-Datei, die zu Laufzeit fertiggeschrieben und aus der die Sounddatei dann geladen wird. Code: [Embed(source = "swf.bin", mimeType = "application/octet-stream")] static private const SoundSWF: Class; . Folgender Code liest die MP3-Daten und liest die Anzahl der Samples, sowie die Bit- und Samplerate aus. Bei den Eigenschaften "Stereo" und "16bit" weiß ich nicht wie ich die abfragen soll ~~~. Aber es geht erstmal so.Code: private function analyzeMP3Data(data: ByteArray): Object {
//see http://www.mp3-tech.org/programmer/frame_header.html
//constants
const bitratesV1L1: Array = new Array(0,32,64,96,128,160,192,224,256,288,329,352,384,416,448,0);
const bitratesV1L2: Array = new Array(0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0);
const bitratesV1L3: Array = new Array(0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0);
const bitratesV2L1: Array = new Array(0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,0);
const bitratesV2L23: Array = new Array(0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 114, 160, 0);
const sampleratesV1: Array = new Array(44100,48000,32000, 0);
const sampleratesV2: Array = new Array(22050,24000,16000, 0);
const sampleratesV25: Array = new Array(11025,12000,8000, 0);
//variables
var rslt: Object = new Object();
var c: int;
var mpegVersion: int;
var layer: int;
var bitrate: int;
var samplerate: int;
var padding: int;
var framesize: int;
var frames: int = 0;
var samplerateArray: Array;
var bitrateArray: Array;
//go to the first frame
while ((data.position < data.length) && (data.readByte() != -1));
//read version byte
c = data.readByte();
mpegVersion = (c >> 3) & 3;
layer = 4 - (c >> 1) & 3;
if (mpegVersion == 1 || layer == 4)
throw new Error("Bad formated version.");
//choose rate data fields
switch(mpegVersion) {
case 0:
case 2:
if(layer==1)
bitrateArray = bitratesV2L1; else
bitrateArray = bitratesV2L23;
if(mpegVersion == 0)
samplerateArray = sampleratesV25; else
samplerateArray = sampleratesV2;
break;
case 3:
switch(layer) {
case 1: bitrateArray = bitratesV1L1; break;
case 2: bitrateArray = bitratesV1L2; break;
case 3: bitrateArray = bitratesV1L3; break;
}
samplerateArray = sampleratesV1;
}
//read bitrate/samplerate byte
c = data.readByte();
bitrate = (c >> 4) & 15;
samplerate = (c >> 2) & 3;
//count frames
do {
padding = (c >> 1) & 1;
frames++;
framesize = 144000 * bitrateArray[bitrate] / samplerateArray[samplerate] + padding;
data.position += framesize - 3;
if(data.position < data.length) {
data.readByte(); //frame start
data.readByte(); //version
c = data.readByte();
}
} while (data.position < data.length);
rslt.samples = frames * samplerateArray[samplerate];
rslt.samplerate = samplerateArray[samplerate];
rslt.bitrate = bitrateArray[bitrate];
rslt.is16bit = true;
rslt.isStereo = true;
return rslt;
} .Im wesentlichen wird hier die SWF mit der MP3 aufgebaut und geladen .Code: public function loadBytes(data: ByteArray, name: String): void {
var properties: int = 0;//0x2F
var samples: int = 0;
var mp3Props: Object;
//====> analyze data <====//
try {
mp3Props = analyzeMP3Data(data);
//samples
samples = mp3Props.samples;
//audio properties
switch(mp3Props.samplerate) {
case 11025: properties |= 1 << 2; break;
case 22050: properties |= 2 << 2; break;
case 44100: properties |= 3 << 2; break;
default:
throw new Error("Unsupported sample rate");
}
switch(mp3Props.bitrate) {
//...15 other rates missing...
case 128: properties |= 2 << 4; break;
default:
throw new Error("Unsupported bitrate");
}
if (mp3Props.is16bit)
properties |= 2;
if (mp3Props.isStereo)
properties |= 1;
} catch (e: Error) {
dispatchEvent(new IOErrorEvent(IOErrorEvent.IO_ERROR, false, false, e.message))
}
//set name
_url = name;
//====> build SWF file <====//
//set properties
//Header + needed tags
var swf: ByteArray = ByteArray(new SoundSWF());
swf.endian = Endian.LITTLE_ENDIAN;
swf.position = swf.length;
//Tag: DefineSound
swf.writeShort(0x03BF); //tagID for DefineSound (long header)
swf.writeUnsignedInt(data.length+7);//tag length (+7 -> meta information)
swf.writeShort(1); //object ID
swf.writeByte(properties); //sound properties
swf.writeUnsignedInt(samples); //samples count
swf.writeBytes(data); //sound data
//Trailer
swf.writeUnsignedInt(1 << 6); //EOF
//overwrite length field
swf.position = 4;
swf.writeUnsignedInt(swf.length);
//====> load (sound) SWF file <====//
var onSWFLoaded: Function = function( event: Event ): void {
_snd = Sound( new ( loader.contentLoaderInfo.applicationDomain.getDefinition('SoundItem') as Class )() );
dispatchEvent(new Event(Event.COMPLETE));
}
try {
var loader: Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onSWFLoaded);
loader.loadBytes(swf);
} catch (e: Error) {
dispatchEvent(new IOErrorEvent(IOErrorEvent.IO_ERROR, false, false, "No valid sound data."))
}
} Danke für Popforge, André. |
| | |
| | #7 (permalink) |
| Neuer User Registriert seit: Nov 2008
Beiträge: 14
|
O.o Lame-Tags sagen mir gar nichts... und Google sagt dazu auch nichts :-/. Hast du ein paar gute Links dazu? Derzeit brauche ich Loops nicht, aber vielleicht kommt das ja noch .
Geändert von Lotes (23-02-2009 um 20:58 Uhr) Grund: Grammatik=Käse |
| | |
| | #8 (permalink) |
| Neuer User Registriert seit: Nov 2008
Beiträge: 14
|
Nachtrag: Das mit den 15 anderen Formaten ist Blödsinn xD. An entsprechender Stelle bedeutet 2<<4 einfach: "Format ist MP3" :-). In der SWF-Spezifikation Seite 201 steht's muhahaha. (kann man ja nicht so stehen lassen hier ;-)) |
| | |
| | #9 (permalink) |
| [+] Registriert seit: Dec 2002 Ort: cologne
Beiträge: 2.271
|
Ich denke, wenn das Bit auf MP3 steht, dann liest der Flashplayer alle weiteren Information aus den MP3 Headern (Samplingrate, Bitrate). Lame ist ein MP3 Encoder, der in einem speziellen Tag Encoding-Informationen einschleust, die normalerweise unter den Tisch fallen. Damit lassen sich MP3 beim Decodieren zB. wieder auf die Originallänge kürzen, um sie zB. zu loopen. http://gabriel.mp3-tech.org/mp3infotag.html Geändert von André Michelle (27-02-2009 um 07:37 Uhr) |
| | |
| | #10 (permalink) |
| Neuer User Registriert seit: Nov 2008
Beiträge: 14
| Die Bitrate ist egal und die Samplingrate muss angegeben werden, sonst wird es nicht abgespielt. Das 16bit-Flag wird bei MP3 ignoriert und scheinbar auch das Stereo-Flag. Es ist also nur die Samplingrate und das MP3-Flag entscheidend (und natürlich die Anzahl der Samples).
|
| | |
| | #11 (permalink) |
| muh Registriert seit: Apr 2002 Ort: Freiburg / Stuttgart
Beiträge: 4.338
|
Um das nochmal auszugraben: Das 16 Bit / 8 Bit Flag *muss* auf 1 gestellt werden (also 16 Bit), damit der Sound korrekt abgespielt wird. Um die Informationen aus den MP3-Daten auszulesen kann man mp3infoutil verwenden. (nicht perfekt, aber recht brauchbar) Nicht so ganz klar ist mir die Berechnung vom SampleCount, insbesondere bei VBR bin ich unsicher, was die richtige Lösung ist. Einfach frameCount * 576 (wie man es sonst so als Angabe findet), schneidet am Ende des Sounds ein Stückchen ab Momentan nehme ich die Zahl einfach noch mal zwei, (sollte reichen ) scheint keine Fehler auszulösen (die Tag-Length ist ja auch noch da) aber ist natürlich nicht die feine Art.
__________________ »Carpe diem«, sagte der Graf. (Terry Pratchett: Ruhig Blut!) |
| | |
![]() |
| Lesezeichen |
| Themen-Optionen | |
| Ansicht | |
| |