tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
2
ZUGRIFFE
288
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Eroli Eroli ist offline Mitglied Gold
    Registriert seit
    Mar 2007
    Beiträge
    224
    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:
    Code csharp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    
    byte[] audioLinkBuffer = new byte[1000];
     
                        while (m_MP3Stream.Read(audioLinkBuffer, 0, audioLinkBuffer.Length) != 0)
                        {
                            byte[] b = new byte[audioLinkBuffer.Length / 2];
                            int k = 0;
                            for (int i = 1; i < audioLinkBuffer.Length; i += 4)
                            {
                                for (int j = 0; j <= 1; j++)
                                {
                                    b[k] = audioLinkBuffer[i + j - 1];              // Aus Stereo mach Mono
                                    k++;
                                }
                            }
                            k = 0;
                            byte[] c = new byte[b.Length / 2];
                            for (int i = 0; i + 1 < c.Length; i += 2)
                            {
                                c[k] = b[i + 1];                      // Nur High-Byte filtern (funktioniert nicht)
                                k++;
                            }
                            outputStream.Write(c, 0, c.Length);
                        }
                        outputStream.Flush();
                        outputStream.Close();

    Habt ihr da vielleicht irgendwelche Ideen oder Vorschläge?
     

  2. #2
    Eroli Eroli ist offline Mitglied Gold
    Registriert seit
    Mar 2007
    Beiträge
    224
    Habe herausgefunden, dass 16Bit-PCM im 2er-Komplement gespeichert wird.

    Nun sieht mein Code so aus (ich weiß der ist nicht optimiert):
    Code csharp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
    while (m_MP3Stream.Read(audioLinkBuffer, 0, audioLinkBuffer.Length) != 0)
                        {
                            byte[] b = new byte[audioLinkBuffer.Length / 2];
                            int k = 0;
                            for (int i = 1; i < audioLinkBuffer.Length; i += 4)
                            {
                                for (int j = 0; j <= 1; j++)
                                {
                                    b[k] = audioLinkBuffer[i + j - 1];              // Aus Stereo mach Mono
                                    k++;
                                }
                            }
                            for (int i = 0; i < b.Length; i++)
                            {
                                b[i] = (byte)((255 - b[i]) + 1);   // 2er Komplement
                            }
                            k = 0;
                            byte[] c = new byte[b.Length / 2];
                            for (int i = 0; i + 1 < b.Length; i+=2)
                            {
                                c[k] = (byte)(b[i + 1] / 1);  // High-Byte nehmen
                                k++;
                            }
                            outputStream.Write(c, 0, c.Length);
                        }
                        outputStream.Flush();
                        outputStream.Close();

    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?
    Angehängte Dateien Angehängte Dateien
     

  3. #3
    Avatar von Muepe32
    Muepe32 Muepe32 ist offline Mitglied Brokat
    Registriert seit
    Mar 2011
    Beiträge
    353
    Wäre es von der Idee her nicht besser, wenn du den 16-Bit Wert vom Intervall 0-65535 auf das Intervall 0-255 (8 Bit) abbildest? Damit verlierst du lediglich Genauigkeit, nicht jedoch Toninformationen.
    Also:
    Code csharp:
    1
    2
    
    ushort sample = samples[i];
    byte byteSample = (byte)((sample / 65535.0f) * 255.0f);

    Habe schon länger nichts mehr mit Audio gemacht, aber meiner Meinung nach sollte das eher zum Ziel führen.
     
    Viele Tutorials und Artikel zur Programmierung unter Windows mit C++ und C#. Tägliche Updates und Antworten auf eure Fragen:
    Win32Easy - Blog
    Es würde mich freuen, wenn ihr einen Kommentar postet!

Ähnliche Themen

  1. Aus 2 mach 1
    Von harrry im Forum Flash Plattform
    Antworten: 6
    Letzter Beitrag: 16.10.07, 02:13
  2. Was mach ich mit C++
    Von Incognito im Forum C/C++
    Antworten: 4
    Letzter Beitrag: 19.04.06, 17:54
  3. Wie mach ich,,,,,
    Von jiro.b im Forum Photoshop
    Antworten: 2
    Letzter Beitrag: 25.06.02, 23:22
  4. wie mach ich das in asp?
    Von schiieech im Forum ASP
    Antworten: 3
    Letzter Beitrag: 06.06.02, 20:49
  5. Wie mach ich das?
    Von foxx21 im Forum Videoschnitt, Videotechnik & -produktion
    Antworten: 3
    Letzter Beitrag: 04.02.02, 15:32

Stichworte