diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..fdddb29 --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/Makefile b/Makefile index c6187ec..1f0bea2 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,19 @@ -all: - gcc main.c -o pcm2wav +PROJECT = pcm2wav +CC = gcc +CFLAGS = -Wall +RM = rm -f + +PROG1 = $(PROJECT) +PROG2 = wav2pcm +PROGS = $(PROG1) $(PROG2) + +all: $(PROGS) + +$(PROG1): src/$(PROG1).c + $(CC) $(CFLAGS) $^ -o $@ + +$(PROG2): src/$(PROG2).c + $(CC) $(CFLAGS) $^ -o $@ + clean: - rm pcm2wav + $(RM) $(PROGS) diff --git a/README.md b/README.md new file mode 100644 index 0000000..0559e10 --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +# pcm2wav + +Simple tools for added WAV-header to PCM-data. + +## build + +Type: + +```shell +$ make +``` +## use + +```shell +./wav2pcm test.wav test.wav.pcm +``` + +```shell +./pcm2wav test.wav.pcm test.wav.pcm.wav 2 44100 16 +``` diff --git a/main.c b/main.c deleted file mode 100644 index b7d5d9d..0000000 --- a/main.c +++ /dev/null @@ -1,105 +0,0 @@ -#include "stdio.h" - -typedef unsigned char ID[4]; - -typedef struct -{ - ID chunkID; /* {'f', 'm', 't', ' '} */ - long chunkSize; - - short wFormatTag; - unsigned short wChannels; - unsigned long dwSamplesPerSec; - unsigned long dwAvgBytesPerSec; - unsigned short wBlockAlign; - unsigned short wBitsPerSample; - /* Note: there may be additional fields here, - depending upon wFormatTag. */ -} FormatChunk; - -typedef struct -{ - ID chunkID; /* {'d', 'a', 't', 'a'} */ - long chunkSize; - unsigned char waveformData[]; -} DataChunk; - -void usage(char *command) -{ - printf("usage:\n" - "\t%s pcmfile wavfile channel samplerate bitspersample\n", command); -} - -int main(int argc, char *argv[]) -{ - FILE *pcmfile, *wavfile; - long pcmfile_size, chunk_size; - FormatChunk formatchunk; - DataChunk datachunk; - int i, read_len; - char buf[1024]; - short tmp; - - if (argc != 6) { - usage(argv[0]); - return 1; - } - - pcmfile = fopen(argv[1], "rb"); - if (pcmfile == NULL) { - printf("!Error: Can't open pcmfile.\n"); - return 1; - } - fseek(pcmfile, 0, SEEK_END); - pcmfile_size = ftell(pcmfile); - fseek(pcmfile, 0, SEEK_SET); - - wavfile = fopen(argv[2], "wb"); - if (wavfile == NULL) { - printf("!Error: Can't create wavfile.\n"); - return 1; - } - - fwrite("RIFF", 1, 4, wavfile); - fwrite("xxxx", 1, 4, wavfile); //reserved for the total chunk size - fwrite("WAVE", 1, 4, wavfile); - - formatchunk.chunkID[0] = 'f'; - formatchunk.chunkID[1] = 'm'; - formatchunk.chunkID[2] = 't'; - formatchunk.chunkID[3] = ' '; - formatchunk.chunkSize = sizeof(FormatChunk) - sizeof(ID) - sizeof(long); - formatchunk.wFormatTag = 1; /* uncompressed */ - formatchunk.wChannels = atoi(argv[3]); - formatchunk.dwSamplesPerSec = atoi(argv[4]); - formatchunk.wBitsPerSample = atoi(argv[5]); - formatchunk.wBlockAlign = formatchunk.wChannels * (formatchunk.wBitsPerSample >> 3); - formatchunk.dwAvgBytesPerSec = formatchunk.wBlockAlign * formatchunk.dwSamplesPerSec; - fwrite(&formatchunk, 1, sizeof(formatchunk), wavfile); - - datachunk.chunkID[0] = 'd'; - datachunk.chunkID[1] = 'a'; - datachunk.chunkID[2] = 't'; - datachunk.chunkID[3] = 'a'; - datachunk.chunkSize = pcmfile_size; - fwrite(&datachunk, 1, sizeof(ID)+sizeof(long), wavfile); - - while((read_len = fread(buf, 1, sizeof(buf), pcmfile)) != 0) { - /* revert the endiean */ -#if 0 - for (i=0; i +#include +#include + +#if 1 +#define swap_u16 +#define swap_16 +#define swap_u32 +#define swap_32 +#define swap_u64 +#define swap_64 +#else +#define swap_u16 swap_uint16 +#define swap_16 swap_int16 +#define swap_u32 swap_uint32 +#define swap_32 swap_int32 +#define swap_u64 swap_uint64 +#define swap_64 swap_int64 +#endif + +////////////// Endian swaping functions ////////// + +//! Byte swap unsigned short +uint16_t swap_uint16( uint16_t val ) +{ + return (val << 8) | (val >> 8 ); +} + +//! Byte swap short +int16_t swap_int16( int16_t val ) +{ + return (val << 8) | ((val >> 8) & 0xFF); +} + +//! Byte swap unsigned int +uint32_t swap_uint32( uint32_t val ) +{ + val = ((val << 8) & 0xFF00FF00 ) | ((val >> 8) & 0xFF00FF ); + return (val << 16) | (val >> 16); +} + +//! Byte swap int +int32_t swap_int32( int32_t val ) +{ + val = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0xFF00FF ); + return (val << 16) | ((val >> 16) & 0xFFFF); +} + +//! Byte swap int64 +int64_t swap_int64( int64_t val ) +{ + val = ((val << 8) & 0xFF00FF00FF00FF00ULL ) | ((val >> 8) & 0x00FF00FF00FF00FFULL ); + val = ((val << 16) & 0xFFFF0000FFFF0000ULL ) | ((val >> 16) & 0x0000FFFF0000FFFFULL ); + return (val << 32) | ((val >> 32) & 0xFFFFFFFFULL); +} + +//! Byte swap uint64 +uint64_t swap_uint64( uint64_t val ) +{ + val = ((val << 8) & 0xFF00FF00FF00FF00ULL ) | ((val >> 8) & 0x00FF00FF00FF00FFULL ); + val = ((val << 16) & 0xFFFF0000FFFF0000ULL ) | ((val >> 16) & 0x0000FFFF0000FFFFULL ); + return (val << 32) | (val >> 32); +} + +////////////// Endian swaping wrapper functions ////////// +void fwrite64(int64_t value, FILE *f) +{ + int64_t item = swap_64(value); + fwrite(&item, sizeof(int64_t),1,f); +} + +void fwriteU64(uint64_t value, FILE *f) +{ + uint64_t item = swap_u64(value); + fwrite(&item, sizeof(uint64_t),1,f); +} + + +void fwrite32(int32_t value, FILE *f) +{ + int32_t item = swap_32(value); + fwrite(&item, sizeof(int32_t),1,f); +} + +void fwriteU32(uint32_t value, FILE *f) +{ + uint32_t item = swap_u32(value); + fwrite(&item, sizeof(uint32_t),1,f); +} + +void fwrite16(int16_t value, FILE *f) +{ + int16_t item = swap_16(value); + fwrite(&item, sizeof(int16_t),1,f); +} + +void fwriteU16(uint16_t value, FILE *f) +{ + uint16_t item = swap_u16(value); + fwrite(&item, sizeof(uint16_t),1,f); +} + +void fwrite8(int8_t *value, FILE *f) +{ + fwrite(value, sizeof(int8_t), strlen(value),f); +} + +void fwriteU8(uint8_t *value, FILE *f) +{ + fwrite(value, sizeof(uint8_t), strlen(value),f); +} + +void usage(char *command) +{ + printf("usage:\n" + "\t%s pcmfile wavfile channel samplerate bitspersample\n", command); +} + +int main(int argc, char *argv[]) +{ + FILE *pcmfile, *wavfile; + unsigned long int pcmfile_size, chunk_size, total_size; + int read_len; + int chunkSize = 16; + short audioFormat = 1; + short NumChannels, BitsPerSample, BlockAlign; + int SamplingRate, ByteRate; + unsigned char buf[1024]; + + if (argc != 6) + { + usage(argv[0]); + return 1; + } + + pcmfile = fopen(argv[1], "rb"); + if (pcmfile == NULL) + { + fprintf(stderr, "!Error: Can't open pcmfile.\n"); + return 1; + } + fseek(pcmfile, 0, SEEK_END); + pcmfile_size = ftell(pcmfile); + fseek(pcmfile, 0, SEEK_SET); + total_size = 36 + pcmfile_size; + + wavfile = fopen(argv[2], "wb"); + if (wavfile == NULL) + { + fprintf(stderr, "!Error: Can't create wavfile.\n"); + return 1; + } + NumChannels = atoi(argv[3]); + SamplingRate = atoi(argv[4]); + BitsPerSample = atoi(argv[5]); + ByteRate = NumChannels * BitsPerSample * SamplingRate / 8; + BlockAlign = NumChannels * BitsPerSample / 8; + + fwrite8("RIFF", wavfile); + fwrite32(total_size, wavfile); + fwrite8("WAVE", wavfile); + fwrite8("fmt ", wavfile); + fwrite32(chunkSize, wavfile); + fwrite16(audioFormat, wavfile); + fwrite16(NumChannels, wavfile); + fwrite32(SamplingRate, wavfile); + fwrite32(ByteRate, wavfile); + fwrite16(BlockAlign, wavfile); + fwrite16(BitsPerSample, wavfile); + fwrite8("data", wavfile); + fwrite32(pcmfile_size, wavfile); + fflush(wavfile); + + while((read_len = fread(buf, 1, sizeof(buf), pcmfile)) != 0) + { + if(read_len != fwrite(buf, 1, read_len, wavfile)) + { + fprintf(stderr, "!Error: Can't write wavfile.\n"); + return 1; + } + fflush(wavfile); + } + + fclose(pcmfile); + fclose(wavfile); +} diff --git a/src/wav2pcm.c b/src/wav2pcm.c new file mode 100644 index 0000000..c8be809 --- /dev/null +++ b/src/wav2pcm.c @@ -0,0 +1,57 @@ +#include +#include + +void usage(char *command) +{ + printf("usage:\n" + "\t%s wavfile pcmfile\n", command); +} + +int main(int argc, char *argv[]) +{ + FILE *pcmfile, *wavfile; + unsigned long int wavfile_size; + int read_len; + unsigned char buf[1024]; + + if (argc < 3) + { + usage(argv[0]); + return 1; + } + + wavfile = fopen(argv[1], "rb"); + if (wavfile == NULL) + { + printf("!Error: Can't open wavfile.\n"); + return 1; + } + fseek(wavfile, 0, SEEK_END); + wavfile_size = ftell(wavfile); + if (wavfile_size < 45) + { + printf("!Error: Not data in wavfile.\n"); + return 1; + } + fseek(wavfile, 44, SEEK_SET); + + pcmfile = fopen(argv[2], "wb"); + if (pcmfile == NULL) + { + printf("!Error: Can't create pcmfile.\n"); + return 1; + } + + while((read_len = fread(buf, 1, sizeof(buf), wavfile)) != 0) + { + if(read_len != fwrite(buf, 1, read_len, pcmfile)) + { + fprintf(stderr, "!Error: Can't write pcmfile.\n"); + return 1; + } + fflush(pcmfile); + } + + fclose(pcmfile); + fclose(wavfile); +} diff --git a/wav2pcm.sh b/wav2pcm.sh deleted file mode 100644 index e68696b..0000000 --- a/wav2pcm.sh +++ /dev/null @@ -1 +0,0 @@ -dd if=1.wav of=1.pcm bs=1 skip=44