Hallo zusammen,
für ein Microcontrollerprojekt muss ich eine MP3-Datei stark abspecken,
damit der kleine Controller nicht überfordert ist.
Mittels MP3Sharp dekodiere ich die MP3-Datei in ihre PCM-Rohdaten.
Dann durchlaufe ich diese Daten und versuche sie entsprechend zu
filtern.
Der Schritt Stereo --> Mono hat nach einigen Testen auch gut geklappt,
allerdings kriege ich das 16Bit --> 8 Bit nicht hin.
Wenn ich die Datei mit CoolEditPro öffne, wird sie im Intel 16bit-PCM
Format (LSB, MSB) korrekt abgespielt, also dachte ich mir, dass mir im
zweiten Schritt einfach nur jedes zweites Byte (immer das MSB) nehmen
kann um damit eine 8Bit-Version zu erschaffen.
Hier mein Code (C#)
1
byte[] audioLinkBuffer = new byte[1000];
2
3
while (m_MP3Stream.Read(audioLinkBuffer, 0, audioLinkBuffer.Length) != 0)
4
{
5
byte[] b = new byte[audioLinkBuffer.Length / 2];
6
int k = 0;
7
for (int i = 1; i < audioLinkBuffer.Length; i += 4)
Habt ihr da vielleicht irgendwelche Ideen oder Vorschläge?
Die Version, die obiger Code liefert enthält fast nur volle Amplituden.
Man hört viel Rauschen und im Hintergrund gaaanz gaaanz gaaanz schwach
noch die (Krombacher-)Melodie...
Habe mal 2 Beispieldateien drangehangen, die das Ergebnis zeigen.
Ist schon ein heftiger Schritt von 16Bit zu 8Bit.
Habe das ganz mal parallel in einem Programm gemacht und da kam ich auf
ein ähnliches Ergebnis.
Meint ihr die Umwandlung kann so stimmen? Oder stimmt da etwas mit dem
Rauschen noch nicht?
Dachte ich zuerst auch. Dann hab ich in der letzten Schleife aus der +1
eine +0 gemacht (in allen Vorkommen) und das ist das Ergebnis (siehe
Anhang).
Das kanns ja wohl erst recht nicht sein...
Da läuft der Hase wohl doch noch irgendwo falsch, oder?
finde deine schleifen sehr verwirrend :(
mich würde stutzig machen dass das ergebnis mit 22kHz angezeigt wird,
die originaldatei aber mit 48kHz abgetastet wurde.
Roland M. schrieb:> Das kanns ja wohl erst recht nicht sein...
Also irgenwie würde ich da nicht versuchen besonders "schlau" zu
optimieren...
Nimm die 16bit, schiebe sie um 8 stellen nach rechts und nehme dann die
untersten 8 bit, dann klappt es auch mit dem zweierkomplement. ALso etwa
so:
Hi,
erstmal Danke für die Antwort.
Wenn ich deinen Code quasi "nachschalte", dann krieg ich nur noch wirres
piepsen raus, was wirklich gar nix mehr mit der MP3 an sich zu tun hat.
Der Code (Davor wird aus Stereo noch Mono gemacht, was aber bisher
geklappt hat):
Sorry, mein Fehler. Ich habe vergessen meine Zählvariable in der
For-Schleife zu erhöhen.
Habe das nun nachgeholt, aber das Resultat ist immer noch "erbärmlich"
:-D
Mal zwei Versionen:
Einfach abschneiden:
Roland M. schrieb:> Irgendwie liegt da irgendwo irgendetwas im Argen...
Ja wie gesagt das "arge" sind höchstwahrscheinlich deine Konvertierungen
;)
Was macht den das Float da nun drinne?
dies
1
intsample16Bit=(b[i+1]<<8)|(b[i]);
muss eventuell auch
1
intsample16Bit=(b[i]<<8)|(b[i+1]);
heißen, je nach byteorder!
Das sit aber alles nur stochern im Nebel, mach dir doch eine Datei Mono
16bit maximal 1 sek, dann machst du dir eine Datei Mono 8 bit, dann den
Hexeditor deiner Wahl aufmachen, und einfach mal schauen wie es korrekt
aussehen sollte.
Auch ist das hochladen von MP3s wenig zielführend, da sieht man dann ja
nun überhaupt nicht mehr was du konvertiert hast (ich hoffe doch du
versuchst tatsächlich ein RAW PCM WAV zu konvertieren).
Auch solltest du bedenken dass auf jedenfall der Header angepasst werden
muß!
Höhrt sich an, als ob da signed/unsigned durcheinander gekommen sind.
In welcher Form fallen denn die Daten aus Deinem Program, als raw oder
als wav? Wenn raw, dann mal beim öffnen in CoolEditPro die signedness
ändern. Wenn wav, dann entsprechend in Deinem Programm mit reinrechnen.
Bei 16bit wav sind die Daten normalerweise signed während sie bei 8bit
normalerweise unsigned sind.
Guten Morgen zusammen,
ich habe wirklich 16-bit-pcm Rohdaten. Keine WAVs oder sogar MP3s.
Die floats waren wirklich nur dazu da um einen Wert von 65536 auf 255
abzubilden, damit keine Toninformationen verloren gehen (wie beim
Abschneiden des Low-Bytes), sondern alle Informationen einfach
runtergerechnet werden und es dadurch einfach nur "ungenauer" wird.
Aber es haben ja beide Beispiele nicht befriedigend genug funktioniert.
CoolEditPro hab ich schon benutzt. Dadurch weiß ich ja auch, dass mein
Code, der aus Stereo Mono macht, richtig funktioniert.
Leider hab ich das Vorgehen mit der 1s-Datei noch nicht verstanden. Eine
16-bit-pcm datei hat bei 1s laufzeit doch auch such schon 48.000*2 Byte
Größe (Abtastrate von 48Khz). Wie soll ich da dann etwas im HexEditor
erkennen?
Kannst du mir das Vorgehen vielleicht genauer schildern?
Roland M. schrieb:> ich habe wirklich 16-bit-pcm Rohdaten. Keine WAVs oder sogar MP3s.
Verstehe ich jetzt nich. Du benutzt doch MP3Sharp um MP3 zu lesen. Das
liefert Dir 16Bit PCM Sereo. Dann schneidest Du einen Kanal weg und
machst dadurch Mono draus. Dann versuchst Du aus den 16Bit 8Bit zu
machen und gibst das Ergebnis dann über "outputStream" aus. Nur wohin?
Ist das ein File, was Du dann mit Cooledit kontrollierst oder was?
Schreibst Du vor der der Konvertiererei noch irgendwas in den
"outputStream", irgendeinen Header eventuell? Häng doch mal direkt den
Output, der da rauskommt ran.
Eigentlich müßte es reichen, wenn Du Deine Bytes nochmal konvertierst.
Also etwa so:
Roland M. schrieb:> Die floats waren wirklich nur dazu da um einen Wert von 65536 auf 255> abzubilden, damit keine Toninformationen verloren gehen (wie beim> Abschneiden des Low-Bytes)
Eh... ich will dich ja nicht enttäuschen aber das ist bestenfalls
maximal umständlich du erhältst dadurch nicht mehr Informationen!
Roland M. schrieb:> hat bei 1s laufzeit doch auch such schon 48.000*2 Byte
Dann nimm halt eine halbe Sekunde, es geht nur darum, das man
ausreichend wenig Daten hat um z.B. mal die Rohdaten hier hochzuladen.
Roland M. schrieb:> Wie soll ich da dann etwas im HexEditor> erkennen?
Es würde z.B. reichen wenn du die ersten paar bytes vergleichst,
natürlich müssen dann Quelle und Ausgabe jeweils als RAW PCM vorliegen.
Wieoft willst du eigentlich konvertieren? Was spricht dagegen schon ein
fertiges Programm für die Konvertierung zu nehmen?
Läubi .. schrieb:> Eh... ich will dich ja nicht enttäuschen aber das ist bestenfalls> maximal umständlich du erhältst dadurch nicht mehr Informationen!
Verstehe schon, aber es war ja sowieso nur eine Alternative. Kann man
auch einfach weglassen...
> dies>> int sample16Bit = (b[i + 1] << 8) | (b[i]);>> muss eventuell auch>> int sample16Bit = (b[i] << 8) | (b[i + 1]);>> heißen, je nach byteorder!
Ich habe natürlich bereits beide Möglichkeiten ausprobiert. Bei der
Möglichkeit, die im obigen Beispielcode nicht gelistet ist, war quasi
nur Rauschen zu hören.
> Dann nimm halt eine halbe Sekunde, es geht nur darum, das man> ausreichend wenig Daten hat um z.B. mal die Rohdaten hier hochzuladen.
Ich werde noch die oben beschriebenen Möglichkeiten testen und dann ein
entsprechendes Beispiel hier hochladen.
> Wieoft willst du eigentlich konvertieren? Was spricht dagegen schon ein> fertiges Programm für die Konvertierung zu nehmen?
Da ich die Konvertierung für ein Uni-Projekt benötige, möchte ich gerne
auf externe Programme verzichten. Sollte ja auch eigentlich einfach
möglich sein.
@ ... (Gast):
Ich werde deine Vorschläge gleich mal ausprobieren und mich dann mit
Neuigkeiten zurückmelden.
Schonmal vielen Dank an alle helfenden Hände :-)
(Die andere Codealternative mit der If-Bedingung hat genau so
funktioniert)
Erstmal vielen vielen Dank an Dich und auch alle anderen für eure Hilfe
:-)
Hab euch nochmal das Beispiel angehangen.
Schönen Tag noch und nochmals Danke :-)
Roland M. schrieb:> (Die andere Codealternative mit der If-Bedingung hat genau so> funktioniert)
Machen ja im Endeffekt auch beide das gleiche :)
Wie ich drauf gekommen bin? Ich hab Dein Original MP3 mittels Audacity
in Raw 8Bit PCM Mono konvertiert, sowohl als signed als auch als
unsigned Version. Danach hab ich diese raw-Files in CoolEditPro
importiert, hierbai kann man ebenfalls wählen, ob die Daten signed oder
unsigned sind. Wählt man das verkehrte, klingt es genau wie Deine
KrombacherTruncated.mp3. Anschließend hab ich mir die Unterschiede der
beiden raw-Files in hex angesehen und bin so auf die 128 gekommen.