gbaconv

A set of tools aimed at GameBoy Advance developers
Log | Files | Refs | README | LICENSE

wav2gba.c (2360B)


      1 /*
      2  * GBAconv 1.00
      3  * Copyright (c) 2002-2019, Frederic Cambus
      4  * https://github.com/fcambus/gbaconv
      5  *
      6  * WAV to GBA Converter
      7  *
      8  * Created:      2002-12-10
      9  * Last Updated: 2019-05-09
     10  *
     11  * GBAconv is released under the BSD 2-Clause license.
     12  * See LICENSE file for details.
     13  */
     14 
     15 #include <fcntl.h>
     16 #include <stdio.h>
     17 #include <stdlib.h>
     18 #include <string.h>
     19 #include <unistd.h>
     20 #include <sys/mman.h>
     21 #include <sys/stat.h>
     22 
     23 #define WAVE_HEADER_LENGTH 44
     24 
     25 char *input_file_buffer;
     26 
     27 struct wave_header {
     28 	char chunk_ID[4];
     29 	unsigned int chunk_size;
     30 	char format[4];
     31 	char fmt_chunk[4];
     32 	unsigned int fmt_chunk_size;
     33 	unsigned short int audio_format;
     34 	unsigned short int channels;
     35 	unsigned int sample_rate;
     36 	unsigned int byte_rate;
     37 	unsigned short int block_align;
     38 	unsigned short int bits_per_sample;
     39 	char data_chunk[4];
     40 	unsigned int data_chunk_size;
     41 } __attribute__((packed)) wave_header;
     42 
     43 int main(int argc, char *argv[])
     44 {
     45 	int fd;
     46 	struct stat st;
     47 
     48 	if (argc != 3) {
     49 		printf("USAGE: wav2gba input.wav array_name (Input File must be 8-bit, MONO)\n\n");
     50 		return EXIT_SUCCESS;
     51 	}
     52 
     53 	fd = open(argv[1], O_RDONLY);
     54 	if (fd == -1)
     55 		return EXIT_FAILURE;
     56 
     57 	if (fstat(fd, &st) == -1) {
     58 		close(fd);
     59 		return EXIT_FAILURE;
     60 	}
     61 
     62 	/* mmap input file into memory */
     63 	input_file_buffer = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
     64 	if (input_file_buffer == MAP_FAILED) {
     65 		close(fd);
     66 		return EXIT_FAILURE;
     67 	}
     68 
     69 	if (st.st_size < WAVE_HEADER_LENGTH) {
     70 		printf("ERROR: Input File is not a WAV file\n\n");
     71 		return EXIT_FAILURE;
     72 	}
     73 
     74 	/* Check that the file is a valid 8-bit MONO WAV */
     75 	memcpy(&wave_header, input_file_buffer, WAVE_HEADER_LENGTH);
     76 
     77 	if (wave_header.channels != 1) {
     78 		printf("ERROR: Input File is not MONO\n\n");
     79 		return EXIT_FAILURE;
     80 	}
     81 
     82 	if (wave_header.bits_per_sample != 8) {
     83 		printf("ERROR: Input File is not 8-bit\n\n");
     84 		return EXIT_FAILURE;
     85 	}
     86 
     87 	fprintf(stderr, "INPUT  FILE: %s (8-bit, MONO, %i Hz)\n", argv[1], wave_header.sample_rate);
     88 
     89 	fprintf(stdout, "const s8 %s[] = {", argv[2]);
     90 
     91 	for (size_t loop = 0; loop < st.st_size - WAVE_HEADER_LENGTH; loop++) {
     92 		if (loop % 10 == 0)
     93 			fprintf(stdout, "\n\t");
     94 
     95 		fprintf(stdout, "0x%x,", input_file_buffer[WAVE_HEADER_LENGTH + loop] + 128);
     96 	}
     97 
     98 	fprintf(stdout, "\n};\n");
     99 
    100 	/* Terminate Program */
    101 	munmap(input_file_buffer, st.st_size);
    102 	close(fd);
    103 
    104 	return EXIT_SUCCESS;
    105 }