spAudio
Loading...
Searching...
No Matches
rec.c
#include <stdio.h>
#include <sp/spBaseLib.h>
#include <sp/spAudio.h>
#include <sp/spWave.h>
#include <sp/spMain.h>
#ifdef SP_SUPPORT_AUDIO
static double samp_freq = 8000.0;
static int num_channel = 1;
static int samp_bit = 16;
static double rec_time = 3.0;
static long buffer_size = 1024;
static int num_buffer;
static char format_string[SP_MAX_LINE] = "wav";
static spBool nonblock_flag = SP_FALSE;
static char *driver_name = NULL;
static char *plugin_search_path = NULL;
static spBool help_flag;
static int debug_level = -1;
static spOptions options;
static spOption option[] = {
{"-t", "-time", "recording time [sec]", NULL,
SP_TYPE_DOUBLE, &rec_time, "3.0"},
{"-f", "-freq", "sampling frequency for raw data [Hz]", NULL,
SP_TYPE_DOUBLE, &samp_freq, "8000.0"},
{"-c", "-channel", "number of channel", NULL,
SP_TYPE_INT, &num_channel, "1"},
{"-b", "-bit", "bits per sample", NULL,
SP_TYPE_INT, &samp_bit, "16"},
{"-F", "-format", "file format (wav|raw|swap|little|big)", NULL,
SP_TYPE_STRING_A, format_string, "wav"},
{"-buf", NULL, "buffer size", NULL,
SP_TYPE_LONG, &buffer_size, "1024"},
{"-nbuf", NULL, "number of buffers (valid only on Windows)", NULL,
SP_TYPE_INT, &num_buffer, "16"},
{"-n", "-nonblock", "record with nonblocking mode", NULL,
SP_TYPE_BOOLEAN, &nonblock_flag, SP_FALSE_STRING},
{"-driver", NULL, "audio driver name", NULL,
SP_TYPE_STRING, &driver_name, NULL},
{"-path", NULL, "plugin search path", NULL,
SP_TYPE_STRING, &plugin_search_path, NULL},
{"-debug", NULL, "debug level", NULL,
SP_TYPE_INT, &debug_level, NULL},
{"-help", "-h", "display this message", NULL,
SP_TYPE_BOOLEAN, &help_flag, SP_FALSE_STRING},
};
static const char *filelabel[] = {
"<filename...>",
};
int spMain(int argc, char *argv[])
{
spBool swap;
spBool wav_flag;
long length;
long total_length;
long nwrite, nread;
short *data;
const char *filename;
FILE *fp;
spAudio audio;
spWaveInfo wave_info;
spSetHelpMessage(&help_flag, "Record sound file");
options = spGetOptions(argc, argv, option, filelabel);
spGetOptionsValue(argc, argv, options);
spSetDebugLevel(debug_level);
if (!spStrNone(plugin_search_path)) {
spDebug(-10, "spMain", "plugin_search_path: %s\n", plugin_search_path);
spSetPluginSearchPath(plugin_search_path);
}
swap = SP_FALSE;
wav_flag = SP_FALSE;
spDebug(-10, NULL, "samp_freq = %f, num_channel = %d, buffer_size = %ld, format_string = %s\n",
samp_freq, num_channel, buffer_size, format_string);
if (strcaseeq(format_string, "wav")) {
wav_flag = SP_TRUE;
} else if (strcaseeq(format_string, "swap")
|| (strcaseeq(format_string, "little") && BYTE_ORDER == BIG_ENDIAN)
|| (strcaseeq(format_string, "big") && BYTE_ORDER == LITTLE_ENDIAN)) {
swap = SP_TRUE;
}
if ((audio = spInitAudioDriver(driver_name)) == NULL) {
spError(1, "Can't initialize audio.\n");
}
filename = spGetFile(options);
if (filename == NULL) {
spError(1, "Not enough files.\n");
}
spInitWaveInfo(&wave_info);
wave_info.samp_rate = samp_freq;
wave_info.num_channel = num_channel;
wave_info.length = 1;
wave_info.samp_bit = samp_bit;
spSetAudioSampleRate(audio, wave_info.samp_rate);
spSetAudioChannel(audio, wave_info.num_channel);
spSetAudioSampleBit(audio, samp_bit);
spSetAudioBufferSize(audio, buffer_size);
spSetAudioNumBuffer(audio, num_buffer);
if (nonblock_flag == SP_TRUE) {
}
/* open output audio device */
if (!spOpenAudioDevice(audio, "ro")) {
spError(1, "Can't open audio device.\n");
}
spGetAudioSampleRate(audio, &wave_info.samp_rate);
spGetAudioChannel(audio, &wave_info.num_channel);
total_length = (long)spRound(wave_info.samp_rate * rec_time) * wave_info.num_channel;
/*length = buffer_size / 2;*/
length = 8 * buffer_size;
length = MIN(total_length, length);
data = xspAlloc(length, short);
/* open file */
if (NULL == (fp = spOpenFile(filename, "wb"))) {
spError(1, "Can't open file: %s\n", filename);
}
if (wav_flag == SP_TRUE) {
/* write wave information */
if (spWriteWavInfo(&wave_info, fp) == SP_FALSE) {
spError(1, "Can't write wave information: %s\n", filename);
}
}
wave_info.length = 0;
while (wave_info.length < total_length) {
if (wave_info.length + length > total_length) {
length = total_length - wave_info.length;
}
/* read data from audio device */
if ((nread = spReadAudio(audio, data, length)) <= 0) {
break;
}
spDebug(1, NULL, "nread = %ld, length = %ld\n", nread, length);
if (nread > 0) {
if (wav_flag == SP_TRUE) {
nwrite = spWriteWavData(&wave_info, data, nread, fp);
} else {
if (wave_info.samp_bit == 8) {
nwrite = fwritebyte(data, nread, fp);
} else {
nwrite = fwriteshort(data, nread, swap, fp);
}
}
spDebug(1, NULL, "nwrite = %ld, wave_info.length = %ld\n",
nwrite, wave_info.length);
wave_info.length += nwrite;
}
}
/* close audio device */
if (wav_flag == SP_TRUE) {
wave_info.length /= wave_info.num_channel;
/* write wave information */
if (spWriteWavInfo(&wave_info, fp) == SP_FALSE) {
spError(1, "Can't write wave information: %s\n", filename);
}
}
/* close file */
printf("%s:\n", filename);
printf(" ");
if (!spStrNone(wave_info.file_desc)) {
printf("Format: %s\n", wave_info.file_desc);
}
printf("Number of Channels: %d, Sampling Rate: %.0f [Hz]\n",
wave_info.num_channel, wave_info.samp_rate);
printf(" ");
printf("Bits/Sample: %d, Data Length: %ld\n",
wave_info.samp_bit, (long)wave_info.length);
return 0;
}
#else
int spMain(int argc, char *argv[])
{
spError(1, "Audio is not supported.\n");
return 0;
}
#endif
A class to handle audio I/O.
#define spFreeAudioDriver(audio)
Definition spAudio.h:373
#define SP_AUDIO_NONBLOCKING
Definition spAudio.h:59
void spSetMessageFlag(int flag)
void spError(int status, const char *format,...)
void spSetDebugLevel(int level)
FILE * spOpenFile(const char *path, const char *mode)
double spRound(double x)
void spDebug(int level, const char *func_name, const char *format,...)
int spCloseFile(FILE *stream)
#define SP_FALSE_STRING
int spBool
#define SP_TRUE
#define spStrNone(string)
#define SP_FALSE
#define xspAlloc(n, type)
#define spGetOptions(argc, argv, option, file_label)
struct _spOptions * spOptions
void spGetOptionsValue(int argc, char **argv, spOptions options)
const char * spGetFile(spOptions options)
void spSetHelpMessage(spBool *flag, const char *format,...)
void spSetPluginSearchPath(const char *pathlist)
spAudio spInitAudioDriver(const char *driver_name)
spBool spGetAudioSampleRate(spAudio audio, double *samp_rate)
spBool spGetAudioChannel(spAudio audio, int *num_channel)
spBool spSetAudioBlockingMode(spAudio audio, int block_mode)
spBool spSetAudioBufferSize(spAudio audio, int buffer_size)
spBool spSetAudioSampleBit(spAudio audio, int samp_bit)
spBool spSetAudioSampleRate(spAudio audio, double samp_rate)
spBool spOpenAudioDevice(spAudio audio, const char *mode)
spBool spSetAudioNumBuffer(spAudio audio, int num_buffer)
long spReadAudio(spAudio audio, void *data, long length)
spBool spSetAudioChannel(spAudio audio, int num_channel)
spBool spCloseAudioDevice(spAudio audio)
spBool spInitWaveInfo(spWaveInfo *wave_info)
Definition spWave.h:43
int samp_bit
Definition spWave.h:49
spLong length
Definition spWave.h:53
double samp_rate
Definition spWave.h:51
int num_channel
Definition spWave.h:50
char file_desc[SP_WAVE_FILE_DESC_SIZE]
Definition spWave.h:45