/* * Copyright (C) 2008 Tilman Sauerbeck (tilman at code-monkey de) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /* Converts Archimedean Dynasty (aka Schleichfahrt) sound files * to Wave files. * Both mono and stereo files are supported. */ #include #include #include #include #define WAVE_HEADER_SIZE 44 #define PCM_HEADER_SIZE 31 #define BITS_PER_SAMPLE 8 #define PUT_16(buf, val) do { \ uint16_t tmp = SDL_SwapLE16 (val); \ memcpy (buf, &tmp, sizeof (tmp)); \ buf += sizeof (tmp); \ } while (0) #define PUT_32(buf, val) do { \ uint32_t tmp = SDL_SwapLE32 (val); \ memcpy (buf, &tmp, sizeof (tmp)); \ buf += sizeof (tmp); \ } while (0) int main (int argc, char **argv) { FILE *file_right = NULL; int arg_n = 1; if (!argc) fprintf (stderr, "usage: convert_ad_pcm LEFT.PCM " "[RIGHT.PCM] OUTPUT.WAV"); FILE *file_left = fopen (argv[arg_n++], "rb"); /* The right channel's input file is optional. */ if (argc == 4) file_right = fopen (argv[arg_n++], "rb"); uint8_t pcm_header_left[PCM_HEADER_SIZE]; fread (pcm_header_left, PCM_HEADER_SIZE, 1, file_left); if (file_right) fseek (file_right, PCM_HEADER_SIZE, SEEK_SET); uint32_t num_samples; memcpy (&num_samples, &pcm_header_left[0], 4); num_samples = SDL_SwapLE32 (num_samples); uint32_t samplerate; memcpy (&samplerate, &pcm_header_left[19], 4); samplerate = SDL_SwapLE32 (samplerate); const int num_channels = file_right ? 2 : 1; const uint32_t bytes_per_sample = BITS_PER_SAMPLE / 8 * num_channels; uint32_t total_size = WAVE_HEADER_SIZE + (bytes_per_sample * num_samples); uint8_t wave_header[WAVE_HEADER_SIZE], *ptr = wave_header; PUT_32 (ptr, 0x46464952); /* "RIFF" */ PUT_32 (ptr, total_size - 8); PUT_32 (ptr, 0x45564157); /* "WAVE" */ PUT_32 (ptr, 0x20746d66); /* "fmt " */ PUT_32 (ptr, 16); /* format chunk length */ PUT_16 (ptr, 1); /* format tag */ PUT_16 (ptr, num_channels); PUT_32 (ptr, samplerate); PUT_32 (ptr, bytes_per_sample * samplerate); PUT_16 (ptr, bytes_per_sample); PUT_16 (ptr, BITS_PER_SAMPLE); PUT_32 (ptr, 0x61746164); /* "data" */ PUT_32 (ptr, total_size - WAVE_HEADER_SIZE); FILE *file_output = fopen (argv[arg_n++], "wb"); fwrite (wave_header, 1, WAVE_HEADER_SIZE, file_output); for (;;) { uint8_t s; size_t n; n = fread (&s, 1, 1, file_left); if (!n) break; fwrite (&s, 1, 1, file_output); if (file_right) { fread (&s, 1, 1, file_right); fwrite (&s, 1, 1, file_output); } } fclose (file_left); if (file_right) fclose (file_right); fclose (file_output); return EXIT_SUCCESS; }