summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRangi <remy.oukaour+rangi42@gmail.com>2022-03-14 22:40:17 -0400
committerRangi <remy.oukaour+rangi42@gmail.com>2022-03-14 22:40:17 -0400
commit4e23a18fac64bd21ab946579135e06ebfa2e34e9 (patch)
tree639bbb673924789ab45249ea783a33a19615ae29
parent340908b68337b24acbe8450761b58cb1b464ebee (diff)
Rewrite tools/pcm.c to use common.h
Fixes #78
-rw-r--r--tools/pcm.c135
1 files changed, 37 insertions, 98 deletions
diff --git a/tools/pcm.c b/tools/pcm.c
index a14e291d..a42ad0ed 100644
--- a/tools/pcm.c
+++ b/tools/pcm.c
@@ -1,78 +1,58 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-
-#define CHUNKID(b1, b2, b3, b4) \
- (uint32_t)((uint32_t)(b1) | ((uint32_t)(b2) << 8) | \
- ((uint32_t)(b3) << 16) | ((uint32_t)(b4) << 24))
-
-size_t file_size(FILE *f) {
- if (fseek(f, 0, SEEK_END) == -1) return 0;
- long f_size = ftell(f);
- if (f_size == -1) return 0;
- if (fseek(f, 0, SEEK_SET) == -1) return 0;
- return (size_t)f_size;
-}
+#define PROGRAM_NAME "pcm"
+#define USAGE_OPTS "infile.wav outfile.pcm"
+
+#include "common.h"
+
+#define CHUNKID(b1, b2, b3, b4) (uint32_t)((uint32_t)(b1) | ((uint32_t)(b2) << 8) | ((uint32_t)(b3) << 16) | ((uint32_t)(b4) << 24))
-int32_t get_uint16le(uint8_t *data, size_t size, size_t i) {
- return i + 2 >= size ? -1 :
- (int32_t)data[i] | ((int32_t)data[i+1] << 8);
+int32_t get_uint16le(uint8_t *data, long size, long i) {
+ return i + 2 < size ? (int32_t)data[i] | ((int32_t)data[i + 1] << 8) : -1;
}
-int64_t get_uint32le(uint8_t *data, size_t size, size_t i) {
- return i + 4 >= size ? -1 :
- (int64_t)data[i] | ((int64_t)data[i+1] << 8) |
- ((int64_t)data[i+2] << 16) | ((int64_t)data[i+3] << 24);
+int64_t get_uint32le(uint8_t *data, long size, long i) {
+ return i + 4 < size ? (int64_t)data[i] | ((int64_t)data[i + 1] << 8) | ((int64_t)data[i + 2] << 16) | ((int64_t)data[i + 3] << 24) : -1;
}
-uint8_t *wav2pcm(uint8_t *wavdata, size_t wavsize, size_t *pcmsize) {
+uint8_t *wav2pcm(uint8_t *wavdata, long wavsize, size_t *pcmsize) {
int64_t fourcc = get_uint32le(wavdata, wavsize, 0);
if (fourcc != CHUNKID('R', 'I', 'F', 'F')) {
- fputs("WAV file does not start with 'RIFF'\n", stderr);
- return NULL;
+ error_exit("WAV file does not start with 'RIFF'\n");
}
int64_t waveid = get_uint32le(wavdata, wavsize, 8);
if (waveid != CHUNKID('W', 'A', 'V', 'E')) {
- fputs("RIFF chunk does not start with 'WAVE'\n", stderr);
- return NULL;
+ error_exit("RIFF chunk does not start with 'WAVE'\n");
}
- size_t sample_offset = 0;
+ long sample_offset = 0;
int64_t num_samples = 0;
- size_t riffsize = (size_t)get_uint32le(wavdata, wavsize, 4) + 8;
- for (size_t i = 12; i < riffsize;) {
+ int64_t riffsize = get_uint32le(wavdata, wavsize, 4) + 8;
+ for (long i = 12; i < riffsize;) {
int64_t chunkid = get_uint32le(wavdata, wavsize, i);
- int64_t chunksize = get_uint32le(wavdata, wavsize, i+4);
- i += 8;
+ int64_t chunksize = get_uint32le(wavdata, wavsize, i + 4);
if (chunksize == -1) {
- fputs("failed to read sub-chunk size\n", stderr);
- return NULL;
+ error_exit("Failed to read sub-chunk size\n");
}
+ i += 8;
- // require 22050 Hz 8-bit PCM WAV audio
+ // Require 22050 Hz 8-bit PCM WAV audio
if (chunkid == CHUNKID('f', 'm', 't', ' ')) {
int32_t audio_format = get_uint16le(wavdata, wavsize, i);
if (audio_format != 1) {
- fputs("WAV data is not PCM format\n", stderr);
- return NULL;
+ error_exit("WAV data is not PCM format\n");
}
- int32_t num_channels = get_uint16le(wavdata, wavsize, i+2);
+ int32_t num_channels = get_uint16le(wavdata, wavsize, i + 2);
if (num_channels != 1) {
- fputs("WAV data is not mono\n", stderr);
- return NULL;
+ error_exit("WAV data is not mono\n");
}
- int64_t sample_rate = get_uint32le(wavdata, wavsize, i+4);
+ int64_t sample_rate = get_uint32le(wavdata, wavsize, i + 4);
if (sample_rate != 22050) {
- fputs("WAV data is not 22050 Hz\n", stderr);
- return NULL;
+ error_exit("WAV data is not 22050 Hz\n");
}
- int32_t bits_per_sample = get_uint16le(wavdata, wavsize, i+14);
+ int32_t bits_per_sample = get_uint16le(wavdata, wavsize, i + 14);
if (bits_per_sample != 8) {
- fputs("WAV data is not 8-bit\n", stderr);
- return NULL;
+ error_exit("WAV data is not 8-bit\n");
}
}
@@ -82,17 +62,16 @@ uint8_t *wav2pcm(uint8_t *wavdata, size_t wavsize, size_t *pcmsize) {
break;
}
- i += (size_t)chunksize;
+ i += chunksize;
}
if (!num_samples) {
- fputs("WAV data has no PCM samples\n", stderr);
- return NULL;
+ error_exit("WAV data has no PCM samples\n");
}
- // pack 8 WAV samples per PCM byte, clamping each to 0 or 1
+ // Pack 8 WAV samples per PCM byte, clamping each to 0 or 1
*pcmsize = (size_t)((num_samples + 7) / 8);
- uint8_t *pcmdata = malloc(*pcmsize);
+ uint8_t *pcmdata = xmalloc(*pcmsize);
for (int64_t i = 0; i < num_samples; i += 8) {
uint8_t v = 0;
for (int64_t j = 0; j < 8 && i + j < num_samples; j++) {
@@ -100,61 +79,21 @@ uint8_t *wav2pcm(uint8_t *wavdata, size_t wavsize, size_t *pcmsize) {
}
pcmdata[i / 8] = v;
}
-
return pcmdata;
}
int main(int argc, char *argv[]) {
if (argc != 3) {
- fprintf(stderr, "Usage: %s infile.wav outfile.pcm\n", argv[0]);
- return EXIT_FAILURE;
- }
-
- char *wavname = argv[1];
- char *pcmname = argv[2];
-
- FILE *wavfile = fopen(wavname, "rb");
- if (!wavfile) {
- fprintf(stderr, "failed to open for reading: '%s'\n", wavname);
- return EXIT_FAILURE;
- }
-
- size_t wavsize = file_size(wavfile);
- if (!wavsize) {
- fclose(wavfile);
- fprintf(stderr, "failed to get file size: '%s'\n", wavname);
- return EXIT_FAILURE;
- }
-
- uint8_t *wavdata = malloc(wavsize);
- size_t readsize = fread(wavdata, 1, wavsize, wavfile);
- fclose(wavfile);
- if (readsize != wavsize) {
- fprintf(stderr, "failed to read: '%s'\n", wavname);
- return EXIT_FAILURE;
+ usage_exit(1);
}
+ long wavsize;
+ uint8_t *wavdata = read_u8(argv[1], &wavsize);
size_t pcmsize;
uint8_t *pcmdata = wav2pcm(wavdata, wavsize, &pcmsize);
- free(wavdata);
- if (!pcmdata) {
- fprintf(stderr, "failed to convert: '%s'\n", wavname);
- return EXIT_FAILURE;
- }
+ write_u8(argv[2], pcmdata, pcmsize);
- FILE *pcmfile = fopen(pcmname, "wb");
- if (!pcmfile) {
- fprintf(stderr, "failed to open for writing: '%s'\n", pcmname);
- return EXIT_FAILURE;
- }
-
- size_t writesize = fwrite(pcmdata, 1, pcmsize, pcmfile);
+ free(wavdata);
free(pcmdata);
- fclose(pcmfile);
- if (writesize != pcmsize) {
- fprintf(stderr, "failed to write: '%s'\n", pcmname);
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
+ return 0;
}