summaryrefslogtreecommitdiffstats
path: root/parecord
diff options
context:
space:
mode:
Diffstat (limited to 'parecord')
-rw-r--r--parecord/Makefile14
-rw-r--r--parecord/audio_types.c6
-rw-r--r--parecord/audio_types.h4
-rw-r--r--parecord/audio_types.obin0 -> 5704 bytes
-rw-r--r--parecord/parecord.c102
5 files changed, 90 insertions, 36 deletions
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
--- /dev/null
+++ b/parecord/audio_types.o
Binary files 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 <signal.h>
#include <getopt.h>
#include <errno.h>
+#include <sys/stat.h>
#include <pulse/simple.h>
-#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;
}