Commit 6017b6eb authored by Martin Storsjo's avatar Martin Storsjo

Rewrite the wav reader in pure C

Also change camel case identifier names to lowercase with
underscores.
parent 550d8f0e
......@@ -107,7 +107,7 @@ endif
bin_PROGRAMS = amrwb-enc$(EXEEXT)
amrwb_enc_LDADD = libvo-amrwbenc.la
amrwb_enc_SOURCES = amrwb-enc.cpp wavreader.cpp
amrwb_enc_SOURCES = amrwb-enc.cpp wavreader.c
noinst_HEADERS = wavreader.h
......
......@@ -80,9 +80,13 @@ int main(int argc, char *argv[]) {
FILE* out;
WavReader wav(infile);
void* wav = wav_read_open(infile);
if (!wav) {
fprintf(stderr, "Unable to open wav file %s\n", infile);
return 1;
}
int format, sampleRate, channels, bitsPerSample;
if (!wav.getHeader(&format, &channels, &sampleRate, &bitsPerSample, NULL)) {
if (!wav_get_header(wav, &format, &channels, &sampleRate, &bitsPerSample, NULL)) {
fprintf(stderr, "Bad wav file %s\n", infile);
return 1;
}
......@@ -110,7 +114,7 @@ int main(int argc, char *argv[]) {
fwrite("#!AMR-WB\n", 1, 9, out);
while (true) {
int read = wav.readData(inputBuf, inputSize);
int read = wav_read_data(wav, inputBuf, inputSize);
read /= channels;
read /= 2;
if (read < 320)
......@@ -127,6 +131,7 @@ int main(int argc, char *argv[]) {
delete [] inputBuf;
fclose(out);
E_IF_exit(amr);
wav_read_close(wav);
return 0;
}
......
......@@ -17,69 +17,84 @@
*/
#include "wavreader.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#define TAG(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
uint32_t WavReader::readTag() {
struct wav_reader {
FILE *wav;
uint32_t data_length;
int format;
int sample_rate;
int bits_per_sample;
int channels;
int byte_rate;
int block_align;
};
static uint32_t read_tag(struct wav_reader* wr) {
uint32_t tag = 0;
tag = (tag << 8) | fgetc(wav);
tag = (tag << 8) | fgetc(wav);
tag = (tag << 8) | fgetc(wav);
tag = (tag << 8) | fgetc(wav);
tag = (tag << 8) | fgetc(wr->wav);
tag = (tag << 8) | fgetc(wr->wav);
tag = (tag << 8) | fgetc(wr->wav);
tag = (tag << 8) | fgetc(wr->wav);
return tag;
}
uint32_t WavReader::readInt32() {
static uint32_t read_int32(struct wav_reader* wr) {
uint32_t value = 0;
value |= fgetc(wav) << 0;
value |= fgetc(wav) << 8;
value |= fgetc(wav) << 16;
value |= fgetc(wav) << 24;
value |= fgetc(wr->wav) << 0;
value |= fgetc(wr->wav) << 8;
value |= fgetc(wr->wav) << 16;
value |= fgetc(wr->wav) << 24;
return value;
}
uint16_t WavReader::readInt16() {
static uint16_t read_int16(struct wav_reader* wr) {
uint16_t value = 0;
value |= fgetc(wav) << 0;
value |= fgetc(wav) << 8;
value |= fgetc(wr->wav) << 0;
value |= fgetc(wr->wav) << 8;
return value;
}
WavReader::WavReader(const char *filename) {
dataLength = 0;
format = 0;
sampleRate = 0;
bitsPerSample = 0;
channels = 0;
byteRate = 0;
blockAlign = 0;
void* wav_read_open(const char *filename) {
struct wav_reader* wr = (struct wav_reader*) malloc(sizeof(*wr));
long data_pos = 0;
memset(wr, 0, sizeof(*wr));
wav = fopen(filename, "rb");
if (wav == NULL)
return;
wr->wav = fopen(filename, "rb");
if (wr->wav == NULL) {
free(wr);
return NULL;
}
long dataPos = 0;
while (true) {
uint32_t tag = readTag();
if (feof(wav))
while (1) {
uint32_t tag, tag2, length;
tag = read_tag(wr);
if (feof(wr->wav))
break;
uint32_t length = readInt32();
length = read_int32(wr);
if (tag != TAG('R', 'I', 'F', 'F') || length < 4) {
fseek(wav, length, SEEK_CUR);
fseek(wr->wav, length, SEEK_CUR);
continue;
}
uint32_t tag2 = readTag();
tag2 = read_tag(wr);
length -= 4;
if (tag2 != TAG('W', 'A', 'V', 'E')) {
fseek(wav, length, SEEK_CUR);
fseek(wr->wav, length, SEEK_CUR);
continue;
}
// RIFF chunk found, iterate through it
while (length >= 8) {
uint32_t subtag = readTag();
if (feof(wav))
uint32_t subtag, sublength;
subtag = read_tag(wr);
if (feof(wr->wav))
break;
uint32_t sublength = readInt32();
sublength = read_int32(wr);
length -= 8;
if (length < sublength)
break;
......@@ -88,54 +103,60 @@ WavReader::WavReader(const char *filename) {
// Insufficient data for 'fmt '
break;
}
format = readInt16();
channels = readInt16();
sampleRate = readInt32();
byteRate = readInt32();
blockAlign = readInt16();
bitsPerSample = readInt16();
wr->format = read_int16(wr);
wr->channels = read_int16(wr);
wr->sample_rate = read_int32(wr);
wr->byte_rate = read_int32(wr);
wr->block_align = read_int16(wr);
wr->bits_per_sample = read_int16(wr);
} else if (subtag == TAG('d', 'a', 't', 'a')) {
dataPos = ftell(wav);
dataLength = sublength;
fseek(wav, sublength, SEEK_CUR);
data_pos = ftell(wr->wav);
wr->data_length = sublength;
fseek(wr->wav, sublength, SEEK_CUR);
} else {
fseek(wav, sublength, SEEK_CUR);
fseek(wr->wav, sublength, SEEK_CUR);
}
length -= sublength;
}
if (length > 0) {
// Bad chunk?
fseek(wav, length, SEEK_CUR);
fseek(wr->wav, length, SEEK_CUR);
}
}
fseek(wav, dataPos, SEEK_SET);
fseek(wr->wav, data_pos, SEEK_SET);
return wr;
}
WavReader::~WavReader() {
fclose(wav);
void wav_read_close(void* obj) {
struct wav_reader* wr = (struct wav_reader*) obj;
fclose(wr->wav);
free(wr);
}
bool WavReader::getHeader(int* format, int* channels, int* sampleRate, int* bitsPerSample, unsigned int* dataLength) {
int wav_get_header(void* obj, int* format, int* channels, int* sample_rate, int* bits_per_sample, unsigned int* data_length) {
struct wav_reader* wr = (struct wav_reader*) obj;
if (format)
*format = this->format;
*format = wr->format;
if (channels)
*channels = this->channels;
if (sampleRate)
*sampleRate = this->sampleRate;
if (bitsPerSample)
*bitsPerSample = this->bitsPerSample;
if (dataLength)
*dataLength = this->dataLength;
return this->format && this->sampleRate;
*channels = wr->channels;
if (sample_rate)
*sample_rate = wr->sample_rate;
if (bits_per_sample)
*bits_per_sample = wr->bits_per_sample;
if (data_length)
*data_length = wr->data_length;
return wr->format && wr->sample_rate;
}
int WavReader::readData(unsigned char* data, unsigned int length) {
if (wav == NULL)
int wav_read_data(void* obj, unsigned char* data, unsigned int length) {
struct wav_reader* wr = (struct wav_reader*) obj;
int n;
if (wr->wav == NULL)
return -1;
if (length > dataLength)
length = dataLength;
int n = fread(data, 1, length, wav);
dataLength -= length;
if (length > wr->data_length)
length = wr->data_length;
n = fread(data, 1, length, wr->wav);
wr->data_length -= length;
return n;
}
......@@ -19,32 +19,19 @@
#ifndef WAVREADER_H
#define WAVREADER_H
#include <stdio.h>
#include <stdint.h>
class WavReader {
public:
WavReader(const char *filename);
~WavReader();
bool getHeader(int* format, int* channels, int* sampleRate, int* bitsPerSample, unsigned int* dataLength);
int readData(unsigned char* data, unsigned int length);
#ifdef __cplusplus
extern "C" {
#endif
private:
uint32_t readTag();
uint32_t readInt32();
uint16_t readInt16();
void* wav_read_open(const char *filename);
void wav_read_close(void* obj);
FILE *wav;
uint32_t dataLength;
int wav_get_header(void* obj, int* format, int* channels, int* sample_rate, int* bits_per_sample, unsigned int* data_length);
int wav_read_data(void* obj, unsigned char* data, unsigned int length);
int format;
int sampleRate;
int bitsPerSample;
int channels;
int byteRate;
int blockAlign;
};
#ifdef __cplusplus
}
#endif
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment