Oprettet tir. d. 02. august 2011 kl. 00:07:09

Panum
Panum (4.895 point. Point ude: 290)

Indlæsning af PCM data (.WAV)

Hejsa,

Jeg står i den situation, at jeg prøver at læse selve lyd-dataen fra en .WAV-fil (bedre kendt som PCM data). Jeg er udemærket klarover at ikke alle WAV-filer er ens, men er 100% sikker på den jeg har brugt af, følger strukturen beskrevet her: https://ccrma.stanford.edu/ (...)

Mit problem er i at når jeg læser samples (som i følge den linkede hjemmeside) er signed ints, og jegprøver at bruge .read() på min .wav fil, får jeg umildbart ikke nogle tal som giver mening.

Har også kigget her: http://princessblade.net/ (...)

Hvor der påståes at der skal bruges short ints (grundet 16-bit), men intet giver det ønskede billede eller det rigtige output af waveformen :(

Her er min wavfil.cpp klasse:


#include <fstream>
#include <math.h>
#include <string>
#include <algorithm>

using namespace std;

class wavfile {
string path;
unsigned int bitsPerSample, sampleRate, filesize, bytesPerSecond, filelength;
fstream file;
float* samples;
public:
wavfile (string);
unsigned int bitspersample ();
unsigned int samplerate ();
unsigned int size ();
unsigned int length ();
unsigned int byterate ();
private:
void instantiate ();
void sampleArray (int, int);



};

wavfile::wavfile(const string p){
    path = p;
    wavfile::instantiate();
}

void wavfile::instantiate(){
            file.open(path.c_str(), ios::in|ios::binary);
            file.seekg(0, ios::end);
           
            filesize = (int) file.tellg();
           
            file.seekg(24, ios::beg);
            file.read ((char *)&sampleRate, sizeof(sampleRate));
           
            file.seekg(34, ios::beg);
            bitsPerSample = (unsigned int) file.get();
           
            file.seekg (28, ios::beg);
            file.read ((char *)&bytesPerSecond, sizeof(bytesPerSecond));
           
            filelength = ceil((double )(filesize-44)/ (double) bytesPerSecond);
           
           
            samples = new float[300];
           
            sampleArray(300, 256);
           
            for(unsigned int i = 0; i < 300; i++){
                            cout << samples[i] << endl;
                        }   
           
       
}

unsigned int wavfile::bitspersample(){
    return bitsPerSample;
}
unsigned int wavfile::samplerate(){
    return sampleRate;
}
unsigned int wavfile::size(){
    return filesize;
}
unsigned int wavfile::length(){
    return filelength;
}
unsigned int wavfile::byterate(){
    return bytesPerSecond;
}
void wavfile::sampleArray(int amount, int precision){
   
    //Sikre at hvert skridt er et multiplicit af 4, sådan så vi rammer et sample (og ikke lander midt i ét)
    unsigned int steplength = (((filesize-44) / (amount*precision))/4)*4;
   
    unsigned int stepAmount = amount*precision;
   
    unsigned int counter = 0;
    int pcounter = 1;
    int currentValue = 0;
    for(unsigned int i = 0; i < stepAmount; i++){
        file.seekg(44+(i*steplength), ios::beg);
       
        short int left;
        short int right;
       
        file.read ((char *)&left, 2);
        file.read ((char *)&right, 2);
       
        int tempValue = max(left, right);
       
           
        if(tempValue > currentValue){
                    currentValue = tempValue;
        }
               
        if(pcounter ==  precision){
                   
       
                    samples[counter] = (float) currentValue / (float) 32767;
                    pcounter = 1;
                    counter++;
                } else {
                    pcounter++;
                }
       
    }
   
   
   
}




Skrevet tir. d. 02. august 2011 kl. 01:09:55| #1

bertelbrander
bertelbrander (17.270 point)
Jeg tror du skal starte med at fortælle os hvad det er du forsøger at gøre i wavfile::sampleArray. jeg forstår ikke rigtigt hvad denne linje skal gøre:
unsigned int steplength = (((filesize-44) / (amount*precision))/4)*4;

Hvis filen ikke er ret stor, bliver steplength 0

Skrevet tir. d. 02. august 2011 kl. 01:47:07| #2

Panum
Panum (4.895 point)
Hej,

Ja, det er klart. Men diverse checks bliver lavet senere, det er som sagt bare en skits til et færdigt program.

Håbede at kommentare kunne forklare det, men så prøver jeg lidt mere uddybende:

(filesize-44) -> Den aktuelle størrelse af selve dataen (uden diverse chunks).

(amount*precision) -> Hvor mange samples der skal benyttes.


2-kanals PCM data er struktureret således:  (L -> Left channel, R -> Right channel)

            L        L            R              R            L        L

Byte    44      45          46          47          48      49  ... osv.

Et sampel består af 4 bytes (LL + RR). Hvert sample starter på 44 + (4 * n)    n = {0, 1, 2 ... }

Det er det som steplength sikre (ie, sådan vi ikke hopper ind på en adresse, hvor vi lander midt i et sample)

Hele mit problem er at jeg ikke har verdens største erfaring med C++ og indlæsningen af binære ting. Synes bare jeg har prøvet så mange ting, så nu måtte jeg prøve at skrive her.

Skrevet tir. d. 02. august 2011 kl. 02:02:40| #3

bertelbrander
bertelbrander (17.270 point)
Umiddelbart tror jeg at du læser rigtigt.
Du skal checke at steplength ikke bliver 0, for så vil du læse den første sample hver eneste gang.

Men prøv at udskrive værdierne på de samples du læser ind, så du kan se om du læser rigtigt.

Skrevet tir. d. 30. august 2011 kl. 15:35:30| #4

CoderBoy
CoderBoy (2.195 point)
Hvis du koder på windows, så kan det anbefales at bruge mmio-funktionerne til det:
http://www.bcbjournal.com/ (...)

Skriv et indlæg




Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] [img]link til billede[/img]
Web- og emailadresser omdannes automatisk til links

Log ind

   

   

Seneste spørgsmål

Updater Hybrid App

Oprettet den 18. april 2012 kl. 13.29
sir_madsen giver 100 point for svar | Giv et svar »

Ansi-c win32API - kan ikke oprette Richedit4.1 kontrol

Oprettet den 16. april 2012 kl. 22.13
cblcbl giver 60 point for svar | Giv et svar »

Iphone Objective C - Sætte image på et imageview.

Oprettet den 7. april 2012 kl. 11.36
lasserasch giver 30 point for svar | Giv et svar »



   




Tips & Tricks fra PC World

Teaser billede

Læserne: Her er vores værste it-indkøb

Det er ikke al it-udstyr, som er det rene guld. Her er nogle af læsernes skrækhistorier.


Anmeldelser fra PC World

Teaser billede

Test: Mobil med Ferrari-design - og en Trabant-motor

Motorola har begået endnu en smartphone med lækkert design og potentiale til at være blandt de bedste. Men den når ikke i mål. Se her hvorfor.


Seneste blogindlæg

Teaser billede

Tvangslukke spørgsmål: Hvad er den bedste løsning?

Hej Vi har mange åbne spørgsmål på Eksperten. Vi ville gerne tvangslukke dem - så et spørgsmål efter f.eks. 6 måneder lukkes. Men der er et par uklarheder som ville være gode at få lidt input til:...


Nyheder fra PC World

Teaser billede

Sådan siger du farvel til Facebook

Læs her, hvordan du dropper Facebook og i stedet anvender nogle brugervenlige alternativer, så du stadig kan være social på nettet.


Nyheder fra Computerworld

Teaser billede

Galleri: De fedeste håndholdte gennem 40 år

Her har du de mest banebrydende håndholdte computere gennem alle tider.


Kurser
Samarbejdspartnere

Udgiver · © 2012 IDG Danmark A/S · Hørkær 18 · 2730 Herlev · Tlf.: 77 300 300 · Fax: 77 300 301 · Brug af personoplysninger