COCKOS
CONFEDERATED FORUMS
Cockos : REAPER : NINJAM : Forums
Forum Home : Register : FAQ : Members List : Search :
Old 06-30-2020, 12:41 PM   #1
SaschArt
Human being with feelings
 
SaschArt's Avatar
 
Join Date: Aug 2013
Posts: 218
Default Read wav files - wrong data

I want to make a plugin that can read audio files. For wav, I made this function:

H file:
Code:
void readWave(char *fname);
CPP file:
Code:
//Wav Header
struct wav_header_t {
    char chunkID[4]; 
    unsigned long chunkSize; 
    char format[4]; 
    char subchunk1ID[4]; 
    unsigned long subchunk1Size;
    unsigned short audioFormat;
    unsigned short numChannels;
    unsigned long sampleRate;
    unsigned long byteRate;
    unsigned short blockAlign;
    unsigned short bitsPerSample;
};

//Chunks
struct chunk_t {
    char ID[4];
    unsigned long size; 
};
void VSTCLASS::readWave(char *fname) {
    FILE *fin = fopen(fname, "rb");

    //Read WAV header
    wav_header_t header;
	fread(&header, sizeof(header), 1, fin);
	
    debugPrint("File Size:", header.chunkSize);
    debugPrint("Format Length:", header.subchunk1Size );
    debugPrint("Format Type:", header.audioFormat);
    debugPrint("Number of Channels:", header.numChannels);
    debugPrint("Sample Rate:", header.sampleRate);
    debugPrint("Sample Rate * Bits/Sample * Channels / 8:", header.byteRate);
    debugPrint("Bits per Sample * Channels / 8.1:", header.blockAlign);
	debugPrint("Bits per Sample:", header.bitsPerSample);

    chunk_t chunk;
    //go to data chunk
    while (true) {
        fread(&chunk, sizeof(chunk), 1, fin);
        debugPrint("chunk", chunk.ID[0], chunk.ID[1], chunk.ID[2], chunk.ID[3], chunk.size);
        if (*(unsigned int *)&chunk.ID == 0x61746164)
            break;
        //skip chunk data bytes
        fseek(fin, chunk.size, SEEK_CUR);
    }

    //Number of samples
    int sample_size = header.bitsPerSample / 8;
    int samples_count = chunk.size * 8 / header.bitsPerSample;
	debugPrint("Samples count:", samples_count);

    short int *value = new short int[samples_count];
	memset(value, 0, sizeof(short int) * samples_count);

    //Reading data
    for (int i = 0; i < samples_count; i++) {
        fread(&value[i]/, sample_size, 1, fin);
		debugPrint("sample:", i,  value[i]/32767.);		
	}
	
	fclose(fin);
}
Data from value[i] are completely wrong. Can you tell me where the mistake is please?
__________________
Audio VST plugins http://vst.saschart.com
SaschArt is offline   Reply With Quote
Old 07-01-2020, 12:40 AM   #2
Tale
Human being with feelings
 
Tale's Avatar
 
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,142
Default

It seems to work just fine here... Are you sure your input is a 16-bit mono WAV file? Are you sure your debugPrint() can handle doubles?

BTW, I also have a WAV file reader (wavread.h) in my WDL repo.
Tale is offline   Reply With Quote
Old 07-01-2020, 04:21 AM   #3
SaschArt
Human being with feelings
 
SaschArt's Avatar
 
Join Date: Aug 2013
Posts: 218
Default

Your wavread.h it's perfect!

For ogg files reading can I find something like that?
__________________
Audio VST plugins http://vst.saschart.com
SaschArt is offline   Reply With Quote
Old 07-01-2020, 07:28 AM   #4
Tale
Human being with feelings
 
Tale's Avatar
 
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,142
Default

Well, I do see a vorbisencdec.h in WDL. However, I have no experience with this. It would seem that this requires a third party SDK, I guess libogg...
Tale is offline   Reply With Quote
Old 10-01-2020, 06:34 AM   #5
SaschArt
Human being with feelings
 
SaschArt's Avatar
 
Join Date: Aug 2013
Posts: 218
Default

I used your wavread.h- thanks!

I need seek function to scan in the wav file. So I added:
Code:
	bool Seek(int sample, int origin) {
		if (!m_fp) return false;
		fseek(m_fp, int((float)sample * m_bps/8.f), origin);
		return true;
	}
wav.Seek(buf_skip, SEEK_CUR) it seems to work but using SEEK_SET returns completely wrong results. Where am I wrong, please?
__________________
Audio VST plugins http://vst.saschart.com
SaschArt is offline   Reply With Quote
Old 10-01-2020, 07:45 AM   #6
SaschArt
Human being with feelings
 
SaschArt's Avatar
 
Join Date: Aug 2013
Posts: 218
Default

Must add wav headers You see any other problem ?
__________________
Audio VST plugins http://vst.saschart.com
SaschArt is offline   Reply With Quote
Old 10-01-2020, 09:08 AM   #7
Tale
Human being with feelings
 
Tale's Avatar
 
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,142
Default

I'm not sure what you're trying to do, but WaveReader::Open() already uses fseek(SEEK_CUR) for skipping unsupported chunks (i.e. everything except "fmt " and "data").
Tale is offline   Reply With Quote
Old 10-02-2020, 02:16 AM   #8
SaschArt
Human being with feelings
 
SaschArt's Avatar
 
Join Date: Aug 2013
Posts: 218
Default

I need to read samples from a given start sample position, not all from start. Using this: wav->Seek(samples_start); then wav->ReadDoubles(...)
__________________
Audio VST plugins http://vst.saschart.com
SaschArt is offline   Reply With Quote
Old 10-02-2020, 06:10 AM   #9
Tale
Human being with feelings
 
Tale's Avatar
 
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,142
Default

Yeah, then doing fseek(SEEK_CUR) after Open() but before Read*() makes sense.

You might also want to take the number of channels into account, but I guess you already can if you do something like:

Code:
wav.Seek(nsamples * wav.get_nch());
Tale is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 11:19 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, vBulletin Solutions Inc.