I am trying to implement a basic example to record a few seconds of audio in FreeBSD, which uses a modified OSS version.
Following the sample files included in the FreeBSD source code and the OSS programming guide I have prepared the following sample program:
But I get a 24000 bytes empty file when I try to record 3 seconds, so it seems like the samples come with all 0 values.
Doing the following works:
Doing
So it seems that I am missing something wrong or I am missing one step.
Following the sample files included in the FreeBSD source code and the OSS programming guide I have prepared the following sample program:
Code:
#include <sys/soundcard.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#define MAX_FILENAME_LENGTH 1024
#define MAX_SECONDS_TO_RECORD 3600 // UP TO 1 HOUR RECORDING
#define MAX_BUFFER_LENGTH 8000*MAX_SECONDS_TO_RECORD
int main(int argc, char *argv[]) {
unsigned char buffer[MAX_BUFFER_LENGTH]; // BUFFER TO STORE AUDIO
char dspfile[MAX_FILENAME_LENGTH]; // /dev/dsp FILENAME
int fd; // /dev/dsp FILE DESCRIPTOR
unsigned int seconds_to_record; // NUMBER OF SECONDS TO RECORD
unsigned long samples_to_record; // NUMBER OF SAMPLES TO RECORD
unsigned long samples_recorded; // NUMBER OF SAMPLES RECORDED
int format; // FORMAT
int channels; // CHANNELS (1=MONO 2=STEREO)
int sampling_rate; // SAMPLING RATE
int error; // AUX VARIABLE ERROR
// STEP 1: READ /dev/dsp PARAMETER
if(argc!=3) {
fprintf(stderr, "ERROR: Incorrect number of arguments.\n");
fprintf(stderr, "USAGE: %s /dev/dsp seconds\n", argv[0]);
exit(1);
} else if( strlen(argv[1]) >= MAX_FILENAME_LENGTH ) {
fprintf(stderr, "ERROR: /dev/dsp filename parameter too long. Maximum size is %d.\n", MAX_FILENAME_LENGTH);
exit(1);
} else {
strncpy(dspfile, argv[1], MAX_FILENAME_LENGTH);
sscanf(argv[2], "%u", &seconds_to_record);
}
if( seconds_to_record >= MAX_SECONDS_TO_RECORD) {
fprintf(stderr, "ERROR: Too many seconds requested. Maximum recording time is %u.\n", MAX_SECONDS_TO_RECORD);
exit(1);
}
// STEP 2: OPEN FILE
fd = open(dspfile, O_RDWR);
if(fd==-1) {
fprintf(stderr, "ERROR: Can not open /dev/dsp file %s. Error code %d %s\n", dspfile, errno, strerror(errno));
exit(1);
}
// STEP 3: CONFIGURE MONO, 8 BITS UNSIGNED SAMPLES, 8KHz SAMPLING RATE
channels = 1;
error = ioctl(fd, SNDCTL_DSP_CHANNELS, &channels);
if(error==-1) {
fprintf(stderr, "ERROR: Can not configure 1 channel. Error code %d %s\n", errno, strerror(errno));
exit(-1);
}
format = AFMT_U8;
error = ioctl(fd, SNDCTL_DSP_SETFMT, &format);
if(error==-1) {
fprintf(stderr, "ERROR: Can not configure audio format. Error code %d %s\n", errno, strerror(errno));
exit(-1);
}
sampling_rate = 8000;
error = ioctl(fd, SNDCTL_DSP_SPEED, &sampling_rate);
if(error==-1) {
fprintf(stderr, "ERROR: Can not configure sampling rate. Error code %d %s\n", errno, strerror(errno));
exit(-1);
}
// STEP 4: RECORD N SAMPLES CORRESPONDING TO THE REQUESTED NUMBER OF SECONDS TO RECORD
samples_to_record = seconds_to_record * 8000;
samples_recorded = 0;
while(samples_to_record > 0) {
ssize_t samples_read = read(fd, buffer + samples_recorded, samples_to_record);
samples_to_record -= (unsigned long)samples_read;
samples_recorded += (unsigned long)samples_read;
write(STDOUT_FILENO, buffer + samples_recorded, samples_read);
}
// STEP 5: CLOSE FILE
if(close(fd)==-1) {
fprintf(stderr, "ERROR: Can not close /dev/dsp file %s. Error code %d %s\n", dspfile, errno, strerror(errno));
exit(1);
}
// DISENGAGE
return(0);
}
But I get a 24000 bytes empty file when I try to record 3 seconds, so it seems like the samples come with all 0 values.
Doing the following works:
Code:
cat /dev/dsp > test.raw
cat test.raw > /dev/dsp
Doing
cat /dev/dsp
also works -characteres are seen on the terminal window-.So it seems that I am missing something wrong or I am missing one step.