From b21605a4d7de3aa116f7991353ac75916fd221ba Mon Sep 17 00:00:00 2001 From: Joursoir Date: Wed, 27 Jan 2021 22:39:41 +0000 Subject: add argv with functional: --format, --channels, --rate; without: --formats --- parecord/audio_types.c | 29 ++++++++++++++++++ parecord/audio_types.h | 7 +++++ parecord/parecord.c | 81 +++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 99 insertions(+), 18 deletions(-) diff --git a/parecord/audio_types.c b/parecord/audio_types.c index 916a5cf..eda78bd 100644 --- a/parecord/audio_types.c +++ b/parecord/audio_types.c @@ -7,6 +7,23 @@ static const struct audio_types_info support_types[] = { {NULL, 0} }; +static const struct audio_formats_info support_formats[] = { + {"U8", PA_SAMPLE_U8}, + {"A_LAW", PA_SAMPLE_ALAW}, + {"MU_LAW", PA_SAMPLE_ULAW}, + {"S16_LE", PA_SAMPLE_S16LE}, + {"S16_BE", PA_SAMPLE_S16BE}, + {"FLOAT32_LE", PA_SAMPLE_FLOAT32LE}, + {"FLOAT32_BE", PA_SAMPLE_FLOAT32BE}, + {"S32_LE", PA_SAMPLE_S32LE}, + {"S32_BE", PA_SAMPLE_S32BE}, + {"S24_LE", PA_SAMPLE_S24LE}, + {"S24_BE", PA_SAMPLE_S24BE}, + {"S24_32LE", PA_SAMPLE_S24_32LE}, + {"S24_32BE", PA_SAMPLE_S24_32BE}, + {NULL, 0} +}; + struct wav_header *init_wav_header(struct wav_header *header, uint32_t size, uint16_t audioFormat, uint16_t numChannels, uint32_t sampleRate, uint32_t bitsPerSample) @@ -43,4 +60,16 @@ int checkAudioType(char *source) off_t getOffset(int format) { return support_types[format].rsv_bytes; +} + +pa_sample_format_t checkAudioFormat(char *source) +{ + int i; + for(i = 0; support_formats[i].name != NULL; i++) { + if(strcmp(source, support_formats[i].name) == 0) { + return support_formats[i].pa_format; + } + } + + return PA_SAMPLE_INVALID; } \ No newline at end of file diff --git a/parecord/audio_types.h b/parecord/audio_types.h index 6b6fd12..d151dce 100644 --- a/parecord/audio_types.h +++ b/parecord/audio_types.h @@ -3,6 +3,7 @@ #include #include +#include #include "wav_header.h" @@ -16,10 +17,16 @@ struct audio_types_info { off_t rsv_bytes; }; +struct audio_formats_info { + const char *name; + pa_sample_format_t pa_format; +}; + struct wav_header *init_wav_header(struct wav_header *header, uint32_t size, uint16_t audioFormat, uint16_t numChannels, uint32_t sampleRate, uint32_t bitsPerSample); int checkAudioType(char *source); off_t getOffset(int format); +pa_sample_format_t checkAudioFormat(char *source); #endif /* AT_AUDIOTYPES_H */ diff --git a/parecord/parecord.c b/parecord/parecord.c index 8c638ba..4fff058 100644 --- a/parecord/parecord.c +++ b/parecord/parecord.c @@ -11,7 +11,14 @@ #include "audio_types.h" +#define PAR_RATE_MIN 2000U +#define PAR_CHANNELS_MIN 1U + #define BUFSIZE 1024 +#define STD_REC_FORMAT PA_SAMPLE_S16LE +#define STD_REC_RATE 44100U +#define STD_REC_CHANNELS PAR_CHANNELS_MIN + volatile static sig_atomic_t flag_do = 1; void handler(int s) @@ -47,39 +54,77 @@ 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 file_type = AUDIO_TYPE_NONE, result; + int fd_output = STDOUT_FILENO, result; + int file_type = AUDIO_TYPE_NONE; + pa_sample_format_t record_format = STD_REC_FORMAT; + uint32_t record_rate = STD_REC_RATE; + uint8_t record_channels = STD_REC_CHANNELS; off_t offset; const struct option long_options[] = { {"help", no_argument, NULL, 'h'}, {"file-type", required_argument, NULL, 't'}, {"file-types", no_argument, NULL, 'T'}, + {"format", required_argument, NULL, 'f'}, + {"formats", no_argument, NULL, 'F'}, + {"channels", required_argument, NULL, 'c'}, + {"rate", required_argument, NULL, 'r'}, {NULL, 0, NULL, 0} }; - while((result = getopt_long(argc, argv, "ht:T", long_options, NULL)) != -1) { + while((result = getopt_long(argc, argv, "ht:Tf:Fc:r:", + long_options, NULL)) != -1) { switch(result) { - case 'h': { - // print help - return 0; - } - case 't': { - file_type = checkAudioType(optarg); - if(file_type != AUDIO_TYPE_NONE) break; - // else print formats (below) + case 'h': { + // print help + return 0; + } + case 't': { + file_type = checkAudioType(optarg); + if(file_type != AUDIO_TYPE_NONE) break; + // else print file types (below) + } + case 'T': { + // print file types + return 0; + } + case 'f': { + record_format = checkAudioFormat(optarg); + if(record_format != PA_SAMPLE_INVALID) break; + // else print formats (below) + } + case 'F': { + // print formats + return 0; + } + case 'c': { + record_channels = atoi(optarg); + + if(record_channels < PAR_CHANNELS_MIN || record_channels > PA_CHANNELS_MAX) { + fprintf(stderr, "Valid channels values are %d - %d\n", + PAR_CHANNELS_MIN, PA_CHANNELS_MAX); + return 1; } - case 'T': { - // print formats - return 0; + break; + } + case 'r': { + record_rate = atoi(optarg); + + if(record_rate < PAR_RATE_MIN || record_rate > PA_RATE_MAX) { + fprintf(stderr, "Valid rate values are %d - %d Hz\n", + PAR_RATE_MIN, PA_RATE_MAX); + return 1; } - default: break; + break; + } + default: break; } } + specification.format = record_format; + specification.channels = record_channels; + specification.rate = record_rate; + 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); -- cgit v1.2.3-18-g5258