From 03693a7e4af4e5f49ffa81bbc655ed1e6816828e Mon Sep 17 00:00:00 2001 From: Joursoir Date: Wed, 27 Jan 2021 13:33:40 +0000 Subject: add interaction main code with audio types; update Makefile for few source --- parecord/Makefile | 14 +++++-- parecord/audio_types.c | 6 +-- parecord/audio_types.h | 4 +- parecord/audio_types.o | Bin 0 -> 5704 bytes parecord/parecord.c | 102 +++++++++++++++++++++++++++++++++++-------------- 5 files changed, 90 insertions(+), 36 deletions(-) create mode 100644 parecord/audio_types.o diff --git a/parecord/Makefile b/parecord/Makefile index eec4ab1..05ed2fc 100644 --- a/parecord/Makefile +++ b/parecord/Makefile @@ -1,8 +1,16 @@ CFLAGS = -Wall -g PULSEFLAGS = -lpulse -lpulse-simple +SOURCES = parecord.c audio_types.c +OBJECTS = ${SOURCES:.c=.o} +EXECUTABLE = parecord -all: - @gcc $(CFLAGS) $(PULSEFLAGS) parecord.c -o parecord +all: $(EXECUTABLE) + +$(EXECUTABLE): $(OBJECTS) + @gcc $(CFLAGS) $(PULSEFLAGS) -o $(EXECUTABLE) $(OBJECTS) + +$(OBJECTS): + @gcc -c $(CFLAGS) $(PULSEFLAGS) $(SOURCES) clean: - @rm -f parecord \ No newline at end of file + @rm -f $(OBJECTS) $(EXECUTABLE) \ No newline at end of file diff --git a/parecord/audio_types.c b/parecord/audio_types.c index 59652e0..0dd1b2f 100644 --- a/parecord/audio_types.c +++ b/parecord/audio_types.c @@ -8,14 +8,14 @@ static const struct audio_format support_formats[] = { }; struct wav_header *init_wav_header(struct wav_header *header, - uint32_t size, uint32_t subchunk1Size, uint16_t audioFormat, - uint16_t numChannels, uint32_t sampleRate, uint32_t bitsPerSample) + uint32_t size, uint16_t audioFormat, uint16_t numChannels, + uint32_t sampleRate, uint32_t bitsPerSample) { header->chunkId = 0x46464952; // = "RIFF" header->chunkSize = size - 8; header->format = 0x45564157; // = "WAVE" header->subchunk1Id = 0x20746d66; // = "fmt " - header->subchunk1Size = subchunk1Size; + header->subchunk1Size = 16; header->audioFormat = audioFormat; header->numChannels = numChannels; header->sampleRate = sampleRate; diff --git a/parecord/audio_types.h b/parecord/audio_types.h index 90a5fc6..2abd11d 100644 --- a/parecord/audio_types.h +++ b/parecord/audio_types.h @@ -15,8 +15,8 @@ struct audio_format { }; struct wav_header *init_wav_header(struct wav_header *header, - uint32_t size, uint32_t subchunk1Size, uint16_t audioFormat, - uint16_t numChannels, uint32_t sampleRate, uint32_t bitsPerSample); + uint32_t size, uint16_t audioFormat, uint16_t numChannels, + uint32_t sampleRate, uint32_t bitsPerSample); int checkAudioFormat(char *source); off_t getOffset(int format); diff --git a/parecord/audio_types.o b/parecord/audio_types.o new file mode 100644 index 0000000..fe04a10 Binary files /dev/null and b/parecord/audio_types.o differ diff --git a/parecord/parecord.c b/parecord/parecord.c index 6588d2e..3f7dda1 100644 --- a/parecord/parecord.c +++ b/parecord/parecord.c @@ -6,19 +6,13 @@ #include #include #include +#include #include -#define BUFSIZE 1024 -volatile sig_atomic_t flag_do = 1; - -enum audio_format { - none, // = 0 - wav // = 1 -}; +#include "audio_types.h" -static const char *correct_formats[] = { - "wav", NULL -}; +#define BUFSIZE 1024 +volatile static sig_atomic_t flag_do = 1; void handler(int s) { @@ -53,9 +47,13 @@ int main(int argc, char *argv[]) pa_simple *connection; pa_sample_spec specification; + specification.format = PA_SAMPLE_S16LE; + specification.channels = 2; + specification.rate = 44100; + int fd_output = STDOUT_FILENO; - int result, i; - enum audio_format file_format = none; + int file_format = AUDIO_FORMAT_NONE, result; + off_t offset; const struct option long_options[] = { {"help", no_argument, NULL, 'h'}, {"format", required_argument, NULL, 'f'}, @@ -67,39 +65,38 @@ int main(int argc, char *argv[]) switch(result) { case 'h': { // print help - break; + return 0; } case 'f': { - for(i = 0; correct_formats[i] != NULL; i++) { - if(strcmp(optarg, correct_formats[i]) == 0) { - file_format = i+1; - break; - } - } - - if(file_format != none) break; + file_format = checkAudioFormat(optarg); + if(file_format != AUDIO_FORMAT_NONE) break; // else print formats (below) } case 'F': { // print formats - break; + return 0; } default: break; } } - + if(argv[optind] != NULL) { mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; fd_output = open(argv[optind], O_WRONLY | O_CREAT| O_TRUNC, mode); if(fd_output == -1) { - perror("[Error] open"); - exit(1); + perror("[Error] open()"); + return 1; } } - specification.format = PA_SAMPLE_S16LE; - specification.channels = 2; - specification.rate = 44100; + // reserve bytes for audio header: + if(file_format != AUDIO_FORMAT_NONE) { + offset = getOffset(file_format); + if(lseek(fd_output, offset, SEEK_SET) == -1) { + perror("[Error] lseek() form header"); + return 1; + } + } connection = pa_simple_new(NULL, argv[0], @@ -135,5 +132,54 @@ int main(int argc, char *argv[]) if(connection) pa_simple_free(connection); + if(file_format != AUDIO_FORMAT_NONE) { + if(lseek(fd_output, 0, SEEK_SET) == -1) { + perror("[Error] lseek()"); + return 1; + } + } + + switch(file_format) + { + case AUDIO_FORMAT_NONE: break; + case AUDIO_FORMAT_WAVE: { + struct stat s; + if(fstat(fd_output, &s) == -1) { + perror("[Error] fstat"); + return 1; + } + + struct wav_header *header = malloc(offset); + init_wav_header(header, s.st_size, 16, 1, + specification.channels, specification.rate, 16); + + #ifdef DEBUG + fprintf(stderr, "chunkId: %#x\n", header->chunkId); + fprintf(stderr, "chunkSize: %#x\n", header->chunkSize); + fprintf(stderr, "format: %#x\n", header->format); + fprintf(stderr, "subchunk1Id: %#x\n", header->subchunk1Id); + fprintf(stderr, "subchunk1Size: %#x\n", header->subchunk1Size); + fprintf(stderr, "audioFormat: %#x\n", header->audioFormat); + fprintf(stderr, "numChannels: %#x\n", header->numChannels); + fprintf(stderr, "sampleRate: %#x\n", header->sampleRate); + fprintf(stderr, "byteRate: %#x\n", header->byteRate); + fprintf(stderr, "blockAlign: %#x\n", header->blockAlign); + fprintf(stderr, "bitsPerSample: %#x\n", header->bitsPerSample); + fprintf(stderr, "subchunk2Id: %#x\n", header->subchunk2Id); + fprintf(stderr, "subchunk2Size: %#x\n", header->subchunk2Size); + #endif + + if(write(fd_output, header, offset) < 0) { + perror("[Error] write()"); + return 1; + } + } + default: break; + } + + if(fd_output != STDOUT_FILENO) { + close(fd_output); + } + return 0; } -- cgit v1.2.3-18-g5258