Puffergröße



  • Hallo,

    ich lese ein 24 bit Audio-File ein, verschiebe es (upper 3 byte) in ein 32 bit File. Das funktioniert auch grundsätzlich einwandfrei.

    Ich hatte zuerst die folgende Methode gewählt. Weil ich komplette Dateien in den RAM lade, ergeben sich hier wegen buf24 und buffer für kurze Zeit 2 Puffer, die in der Summe sehr groß werden können:

    fseek (infile , 0 , SEEK_END);
    size24 = (ftell (infile)); // number of bytes
    size32 = ((size24 - fileoffset) *4/3);
    position = fseek (infile , fileoffset , SEEK_SET); 
    
    unsigned char *buf24 = new unsigned char[size24]; // volle Größe
    unsigned int *buffer = new unsigned int[size32/4 + fileoffset];
    count = fread(buf24, 3, size24/3, infile); // 3 bytes je Sample -> 24 Bits
    
    for (i=0; i < size24/3; i++)
    {
    	buffer[i] = buf24[k+2] << 24 | buf24[k+1] << 16 | buf24[k] << 8; // LSB(0)
    	k += 3;
    }
    delete[] buf24;
    

    Jetzt habe auf folgende Weise einen nur noch 3 byte großen buf24, Problem gelöst, jedoch dauert es doppelt so lange:

    fseek (infile , 0 , SEEK_END);
    size24 = (ftell (infile)); // number of bytes
    size32 = ((size24 - fileoffset) *4/3);
    position = fseek (infile , fileoffset , SEEK_SET); 
    
    unsigned char *buf24 = new unsigned char[3]; // nur noch 3 bytes werden belegt
    unsigned int *buffer = new unsigned int[size32/4 + fileoffset];
    
    for (i=0; i < size24/3; i++)
    {
    count = fread(buf24, 3, 1, infile); // 3 bytes je Sample -> 24 Bits
    buffer[i] = buf24[2] << 24 | buf24[1] << 16 | buf24[0] << 8; // LSB(0)
    }
    delete[] buf24;
    

    Vielleicht bin ich ja auch grundsätzlich auf dem Holzweg. Für einen Hinweis bzgl. einer guten Lösung i.S. Puffergröße/Schneligkeit wäre ich dankbar.

    Gruß
    Thomas



  • Bis auf new und delete sieht das irgendwie nach C aus.
    Was spricht gegen

    char buf24[3072];
    int buf[1024];
    

    auf dem Stack? Kaum Speicherverbrauch und das Einlesen sollte auch schnell gehen.



  • Ein fread() gegen size24/3 fread()s.

    Wundert mich nicht, daß das langsamer ist. Je nachdem wie groß die Dateien sind finde ich die doppelte Laufzeit sogar eher schnell. Ich habe schlimmeres gesehen.


  • Mod

    Ungetestet, aber grob so:

    const unsigned int max24 = 3000;
    const unsigned int max32 = max24 / 3;
    unsigned char buf24[max24]; 
    unsigned int  buf32[max32];
    
    ifstream("input.dat") in;
    ofstream("output.dat") out;
    
    in.seekg(fileoffset);
    
    while (in.read(buf24, max24))
    {
     streamsize read = in.gcount();
     for (i=0; i < read-2; i+=3)
     {
      buf32[i/3] = buf24[i+2] << 24 | buf24[i+1] << 16 | buf24[i] << 8; 
     }
     out.write(buf32, read/3);
    }
    

    In der Art sollte das abgehen wie nix.

    Ich glaube ich könnte die Grenzen falsch haben, kann sein dass bei der Umwandlung einzelne Bytes verloren gehen. Musst du mal sauber durchdenken. Es ging mir gerade nur darum, dir auf die Schnelle zu zeigen, wie man so etwas effizient machen kann.



  • Du könntest z.B. nur buffer32 reservieren, ab Position fileoffset die gesamte 24er-Datei ablegen, und dann von hinten nach vorne die 24-Bit-Werte als 32er an ihre endgültige Position verschieben/konvertieren. Damit kannst Du dir den zusätzlichen Puffer ganz sparen.



  • Vielen Dank! Ich werde die beiden Wege mal durchexerzieren ...



  • Caligulaminus schrieb:

    Du könntest z.B. nur buffer32 reservieren, ab Position fileoffset die gesamte 24er-Datei ablegen, und dann von hinten nach vorne die 24-Bit-Werte als 32er an ihre endgültige Position verschieben/konvertieren. Damit kannst Du dir den zusätzlichen Puffer ganz sparen.

    Habe das jetzt mit einer memmove/memset - Schleife gemacht. Funktioniert hervorragend schnell!

    Dank und Gruß
    Thomas


Anmelden zum Antworten