Skip to content
Browse files

Rewrite the wav reader in pure C

Also change camel case identifier names to lowercase with
underscores.
  • Loading branch information...
1 parent 550d8f0 commit 6017b6eb1ada3e0e9b69fe988dbdc0376e21fe18 @mstorsjo committed Mar 28, 2011
Showing with 181 additions and 168 deletions.
  1. +1 −1 Makefile.am
  2. +8 −3 amrwb-enc.cpp
  3. +162 −0 wavreader.c
  4. +0 −141 wavreader.cpp
  5. +10 −23 wavreader.h
View
2 Makefile.am
@@ -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
View
11 amrwb-enc.cpp
@@ -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;
}
View
162 wavreader.c
@@ -0,0 +1,162 @@
+/* ------------------------------------------------------------------
+ * Copyright (C) 2009 Martin Storsjo
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ * -------------------------------------------------------------------
+ */
+
+#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))
+
+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(wr->wav);
+ tag = (tag << 8) | fgetc(wr->wav);
+ tag = (tag << 8) | fgetc(wr->wav);
+ tag = (tag << 8) | fgetc(wr->wav);
+ return tag;
+}
+
+static uint32_t read_int32(struct wav_reader* wr) {
+ uint32_t value = 0;
+ value |= fgetc(wr->wav) << 0;
+ value |= fgetc(wr->wav) << 8;
+ value |= fgetc(wr->wav) << 16;
+ value |= fgetc(wr->wav) << 24;
+ return value;
+}
+
+static uint16_t read_int16(struct wav_reader* wr) {
+ uint16_t value = 0;
+ value |= fgetc(wr->wav) << 0;
+ value |= fgetc(wr->wav) << 8;
+ return value;
+}
+
+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));
+
+ wr->wav = fopen(filename, "rb");
+ if (wr->wav == NULL) {
+ free(wr);
+ return NULL;
+ }
+
+ while (1) {
+ uint32_t tag, tag2, length;
+ tag = read_tag(wr);
+ if (feof(wr->wav))
+ break;
+ length = read_int32(wr);
+ if (tag != TAG('R', 'I', 'F', 'F') || length < 4) {
+ fseek(wr->wav, length, SEEK_CUR);
+ continue;
+ }
+ tag2 = read_tag(wr);
+ length -= 4;
+ if (tag2 != TAG('W', 'A', 'V', 'E')) {
+ fseek(wr->wav, length, SEEK_CUR);
+ continue;
+ }
+ // RIFF chunk found, iterate through it
+ while (length >= 8) {
+ uint32_t subtag, sublength;
+ subtag = read_tag(wr);
+ if (feof(wr->wav))
+ break;
+ sublength = read_int32(wr);
+ length -= 8;
+ if (length < sublength)
+ break;
+ if (subtag == TAG('f', 'm', 't', ' ')) {
+ if (sublength < 16) {
+ // Insufficient data for 'fmt '
+ break;
+ }
+ 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')) {
+ data_pos = ftell(wr->wav);
+ wr->data_length = sublength;
+ fseek(wr->wav, sublength, SEEK_CUR);
+ } else {
+ fseek(wr->wav, sublength, SEEK_CUR);
+ }
+ length -= sublength;
+ }
+ if (length > 0) {
+ // Bad chunk?
+ fseek(wr->wav, length, SEEK_CUR);
+ }
+ }
+ fseek(wr->wav, data_pos, SEEK_SET);
+ return wr;
+}
+
+void wav_read_close(void* obj) {
+ struct wav_reader* wr = (struct wav_reader*) obj;
+ fclose(wr->wav);
+ free(wr);
+}
+
+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 = wr->format;
+ if (channels)
+ *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 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 > wr->data_length)
+ length = wr->data_length;
+ n = fread(data, 1, length, wr->wav);
+ wr->data_length -= length;
+ return n;
+}
+
View
141 wavreader.cpp
@@ -1,141 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 2009 Martin Storsjo
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- * -------------------------------------------------------------------
- */
-
-#include "wavreader.h"
-
-#define TAG(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
-
-uint32_t WavReader::readTag() {
- uint32_t tag = 0;
- tag = (tag << 8) | fgetc(wav);
- tag = (tag << 8) | fgetc(wav);
- tag = (tag << 8) | fgetc(wav);
- tag = (tag << 8) | fgetc(wav);
- return tag;
-}
-
-uint32_t WavReader::readInt32() {
- uint32_t value = 0;
- value |= fgetc(wav) << 0;
- value |= fgetc(wav) << 8;
- value |= fgetc(wav) << 16;
- value |= fgetc(wav) << 24;
- return value;
-}
-
-uint16_t WavReader::readInt16() {
- uint16_t value = 0;
- value |= fgetc(wav) << 0;
- value |= fgetc(wav) << 8;
- return value;
-}
-
-WavReader::WavReader(const char *filename) {
- dataLength = 0;
- format = 0;
- sampleRate = 0;
- bitsPerSample = 0;
- channels = 0;
- byteRate = 0;
- blockAlign = 0;
-
- wav = fopen(filename, "rb");
- if (wav == NULL)
- return;
-
- long dataPos = 0;
- while (true) {
- uint32_t tag = readTag();
- if (feof(wav))
- break;
- uint32_t length = readInt32();
- if (tag != TAG('R', 'I', 'F', 'F') || length < 4) {
- fseek(wav, length, SEEK_CUR);
- continue;
- }
- uint32_t tag2 = readTag();
- length -= 4;
- if (tag2 != TAG('W', 'A', 'V', 'E')) {
- fseek(wav, length, SEEK_CUR);
- continue;
- }
- // RIFF chunk found, iterate through it
- while (length >= 8) {
- uint32_t subtag = readTag();
- if (feof(wav))
- break;
- uint32_t sublength = readInt32();
- length -= 8;
- if (length < sublength)
- break;
- if (subtag == TAG('f', 'm', 't', ' ')) {
- if (sublength < 16) {
- // Insufficient data for 'fmt '
- break;
- }
- format = readInt16();
- channels = readInt16();
- sampleRate = readInt32();
- byteRate = readInt32();
- blockAlign = readInt16();
- bitsPerSample = readInt16();
- } else if (subtag == TAG('d', 'a', 't', 'a')) {
- dataPos = ftell(wav);
- dataLength = sublength;
- fseek(wav, sublength, SEEK_CUR);
- } else {
- fseek(wav, sublength, SEEK_CUR);
- }
- length -= sublength;
- }
- if (length > 0) {
- // Bad chunk?
- fseek(wav, length, SEEK_CUR);
- }
- }
- fseek(wav, dataPos, SEEK_SET);
-}
-
-WavReader::~WavReader() {
- fclose(wav);
-}
-
-bool WavReader::getHeader(int* format, int* channels, int* sampleRate, int* bitsPerSample, unsigned int* dataLength) {
- if (format)
- *format = this->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;
-}
-
-int WavReader::readData(unsigned char* data, unsigned int length) {
- if (wav == NULL)
- return -1;
- if (length > dataLength)
- length = dataLength;
- int n = fread(data, 1, length, wav);
- dataLength -= length;
- return n;
-}
-
View
33 wavreader.h
@@ -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

0 comments on commit 6017b6e

Please sign in to comment.
Something went wrong with that request. Please try again.