/* RDAIFF version 0.09, a tiny audiofile reading utility in C by Pieter Suurmond, december 30, 2019. Latest version available at: https://ecomaan.nl/c/rdaiff Example program that reads 2 audiofiles. */ #include #include #include /* For strlen(), strcpy(). */ #include "rdaiff.h" /* Demonstrate reading as floats and doubles. */ static void dump_head(short num_channels) { short ch; printf(" frame: "); for (ch = 0; ch < num_channels; ch++) printf("channel%d: ", ch); printf("\n"); } static void dump_frames(const char* filename) { #define MAX_CHANNELS (16) RDAIFFp a; short e; /* Try to open an existing AIFF file. */ e = RDAIFF_open(&a, /* Receive ptr to RDAIFF object here. */ filename); /* String is copied in RDAIFF object. */ if (e) printf("RDAIFF_open(%s) = %d!\n", filename, e); else { long frame; short ch; RDAIFF_info(a, stdout); /* Print file statistics. */ if (RDAIFF_channels(a) > MAX_CHANNELS) { printf("Sorry, channels > %d, please recompile.\n", MAX_CHANNELS); goto close; } printf(" All %ld frames, converted to floats:\n", RDAIFF_frames(a)); dump_head(RDAIFF_channels(a)); for (frame = 0L; frame < RDAIFF_frames(a); frame++) { float sample[MAX_CHANNELS]; e = RDAIFF_float(a, sample, 1); /* Read 1 frame per call. */ if (e) { printf("RDAIFF_float(%s)=%d\n", filename, e); goto close; } printf("%6ld:", frame); for (ch = 0; ch < RDAIFF_channels(a); ch++) printf("%11.6f", sample[ch]); printf("\n"); } e = RDAIFF_rewind(a); /* Makes RDAIFF_frames_togo(a) = RDAIFF_frames. */ printf("\n Again, the same %ld frames, now as shorts:\n", RDAIFF_frames(a)); dump_head(RDAIFF_channels(a)); if (e) { printf("RDAIFF_rewind(%s)=%d", filename, e); goto close; } for (frame = 0L; RDAIFF_frames_togo(a); frame++) { /* Another way of checking available amount. */ short sample[MAX_CHANNELS]; e = RDAIFF_short(a, sample, 1); if (e) { printf("RDAIFF_short(%s)=%d", filename, e); if (e == 1) /* Expected when you read from >16-bit files. */ printf(": Data may not fit in destination type"); printf("!\n"); goto close; } printf("%6ld:", frame); for (ch = 0; ch < RDAIFF_channels(a); ch++) printf("%10d ", (int)sample[ch]); printf("\n"); } close: e = RDAIFF_close(&a); /* Closes file and sets reference a to NULL. */ if (e) printf("RDAIFF_close(%s)=%d\n", filename, e); } printf("\n"); } /* Demonstrate reading as integers. */ static void find_peak(const char* filename) { #define MAX_CHANN (16) RDAIFFp a; short e; /* Try to open an existing AIFF file. */ e = RDAIFF_open(&a, /* Receive ptr to RDAIFF object here. */ filename); /* String is copied in RDAIFF object. */ if (e) printf("RDAIFF_open(%s) = %d!\n", filename, e); else { RDAIFF_info(a, stdout); /* Print file statistics. */ if (RDAIFF_channels(a) > MAX_CHANN) printf("Sorry, channels > %d, please recompile.\n", MAX_CHANN); else { signed char sample[MAX_CHANN]; long frame; long at_frame = -1L; signed char highest = 0; long num_frames = RDAIFF_frames(a); for (frame = 0L; frame < num_frames; frame++) { e = RDAIFF_char(a, sample, 1); /* Read 1 frame per call. */ if (e) { printf("RDAIFF_char(%s)=%d", filename, e); if (e == 1) /* Expected when you read from >8-bit files. */ printf(": Data may not fit in destination type"); printf("!\n"); goto close; } sample[0] = abs(sample[0]); if (sample[0] > highest) /* Only inspect the FIRST channel. */ { highest = sample[0]; at_frame = frame; } } if (highest) printf(" The (1st of) highest peak(s) in 1st channel of '%s'\n \ found at %.4f seconds (absolute value = %.2f %%).\n", filename, (float)at_frame / (float)RDAIFF_samplerate(a), (float)highest / 1.28); else printf("File '%s' is absolutely silent.\n", filename); } close: e = RDAIFF_close(&a); /* Closes file and sets reference a to NULL. */ if (e) printf("RDAIFF_close(%s)=%d\n", filename, e); } printf("\n"); } int main() { printf("Testing the RDAIFF C library.\n"); dump_frames("1.aiff"); /* Input files expected in current directory. */ find_peak ("2.aiff"); return 0; }