You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
235 lines
5.7 KiB
235 lines
5.7 KiB
/*
|
|
* import_oss.c
|
|
*
|
|
* Copyright (C) Jacob Meuser - September 2004
|
|
*
|
|
* This file is part of transcode, a video stream processing tool
|
|
*
|
|
* transcode is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
* any later version.
|
|
*
|
|
* transcode is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with GNU Make; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*
|
|
*/
|
|
|
|
#define MOD_NAME "import_oss.so"
|
|
#define MOD_VERSION "v0.0.3 (2007-11-18)"
|
|
#define MOD_CODEC "(audio) pcm"
|
|
|
|
#include "transcode.h"
|
|
|
|
static int verbose_flag = TC_QUIET;
|
|
static int capability_flag = TC_CAP_PCM;
|
|
|
|
#define MOD_PRE oss
|
|
#include "import_def.h"
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/ioctl.h>
|
|
#ifdef HAVE_SYS_SOUNDCARD_H
|
|
# include <sys/soundcard.h>
|
|
#else
|
|
# ifdef HAVE_SOUNDCARD_H
|
|
# include <soundcard.h>
|
|
# endif
|
|
#endif
|
|
|
|
#include "libtc/optstr.h"
|
|
|
|
static int oss_fd = -1;
|
|
|
|
static int oss_init(const char *, int, int, int);
|
|
static int oss_grab(size_t, char *);
|
|
static int oss_stop(void);
|
|
|
|
|
|
static int oss_init(const char *audio_device,
|
|
int sample_rate, int precision, int channels)
|
|
{
|
|
int encoding, rate = sample_rate;
|
|
|
|
if (!strcmp(audio_device, "/dev/null")
|
|
|| !strcmp(audio_device, "/dev/zero")) {
|
|
return TC_IMPORT_OK;
|
|
}
|
|
|
|
if (precision != 8 && precision != 16) {
|
|
tc_log_warn(MOD_NAME, "bits/sample must be 8 or 16");
|
|
return TC_IMPORT_ERROR;
|
|
}
|
|
|
|
encoding = (precision == 8) ? AFMT_U8 : AFMT_S16_LE;
|
|
|
|
if ((oss_fd = open(audio_device, O_RDONLY)) < 0) {
|
|
tc_log_perror(MOD_NAME, "open audio device");
|
|
return TC_IMPORT_ERROR;
|
|
}
|
|
|
|
if (ioctl(oss_fd, SNDCTL_DSP_SETFMT, &encoding) < 0) {
|
|
tc_log_perror(MOD_NAME, "SNDCTL_DSP_SETFMT");
|
|
return TC_IMPORT_ERROR;
|
|
}
|
|
|
|
if (ioctl(oss_fd, SNDCTL_DSP_CHANNELS, &channels) < 0) {
|
|
tc_log_perror(MOD_NAME, "SNDCTL_DSP_CHANNELS");
|
|
return TC_IMPORT_ERROR;
|
|
}
|
|
|
|
|
|
if (ioctl(oss_fd, SNDCTL_DSP_SPEED, &rate) < 0) {
|
|
tc_log_perror(MOD_NAME, "SNDCTL_DSP_SPEED");
|
|
return TC_IMPORT_ERROR;
|
|
}
|
|
if (rate != sample_rate) {
|
|
tc_log_warn(MOD_NAME, "sample rate requested=%i obtained=%i",
|
|
sample_rate, rate);
|
|
}
|
|
|
|
return TC_IMPORT_OK;
|
|
}
|
|
|
|
static int oss_grab(size_t size, char *buffer)
|
|
{
|
|
int left;
|
|
int offset;
|
|
int received;
|
|
|
|
for (left = size, offset = 0; left > 0;) {
|
|
received = read(oss_fd, buffer + offset, left);
|
|
if (received == 0) {
|
|
tc_log_warn(MOD_NAME, "audio grab: received == 0");
|
|
}
|
|
if (received < 0) {
|
|
if (errno == EINTR) {
|
|
received = 0;
|
|
} else {
|
|
tc_log_perror(MOD_NAME, "audio grab");
|
|
return TC_IMPORT_ERROR;
|
|
}
|
|
}
|
|
if (received > left) {
|
|
tc_log_warn(MOD_NAME,
|
|
"read returns more bytes than requested; "
|
|
"requested: %d, returned: %d",
|
|
left, received);
|
|
return TC_IMPORT_ERROR;
|
|
}
|
|
offset += received;
|
|
left -= received;
|
|
}
|
|
return TC_IMPORT_OK;
|
|
}
|
|
|
|
static int oss_stop(void)
|
|
{
|
|
close(oss_fd);
|
|
oss_fd = -1;
|
|
|
|
if (verbose_flag & TC_STATS) {
|
|
tc_log_warn(MOD_NAME, "totals: (not implemented)");
|
|
}
|
|
|
|
return TC_IMPORT_OK;
|
|
}
|
|
|
|
|
|
/* ------------------------------------------------------------
|
|
* Module interface
|
|
* ------------------------------------------------------------*/
|
|
|
|
MOD_open
|
|
{
|
|
int ret = TC_IMPORT_OK;
|
|
|
|
switch (param->flag) {
|
|
case TC_VIDEO:
|
|
tc_log_warn(MOD_NAME, "unsupported request (init video)");
|
|
ret = TC_IMPORT_ERROR;
|
|
break;
|
|
case TC_AUDIO:
|
|
if (verbose_flag & TC_DEBUG) {
|
|
tc_log_info(MOD_NAME, "OSS audio grabbing");
|
|
}
|
|
if (oss_init(vob->audio_in_file,
|
|
vob->a_rate, vob->a_bits, vob->a_chan)) {
|
|
ret = TC_IMPORT_ERROR;
|
|
}
|
|
break;
|
|
default:
|
|
tc_log_warn(MOD_NAME, "unsupported request (init)");
|
|
ret = TC_IMPORT_ERROR;
|
|
break;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
MOD_decode
|
|
{
|
|
int ret = TC_IMPORT_OK;
|
|
|
|
switch (param->flag) {
|
|
case TC_VIDEO:
|
|
tc_log_warn(MOD_NAME, "unsupported request (decode video)");
|
|
ret = TC_IMPORT_ERROR;
|
|
break;
|
|
case TC_AUDIO:
|
|
if (oss_grab(param->size, param->buffer)) {
|
|
tc_log_warn(MOD_NAME, "error in grabbing audio");
|
|
ret = TC_IMPORT_ERROR;
|
|
}
|
|
break;
|
|
default:
|
|
tc_log_warn(MOD_NAME, "unsupported request (decode)");
|
|
ret = TC_IMPORT_ERROR;
|
|
break;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
MOD_close
|
|
{
|
|
int ret = TC_IMPORT_OK;
|
|
|
|
switch (param->flag) {
|
|
case TC_VIDEO:
|
|
tc_log_warn(MOD_NAME, "unsupported request (close video)");
|
|
ret = TC_IMPORT_ERROR;
|
|
break;
|
|
case TC_AUDIO:
|
|
oss_stop();
|
|
break;
|
|
default:
|
|
tc_log_warn(MOD_NAME, "unsupported request (close)");
|
|
ret = TC_IMPORT_ERROR;
|
|
break;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
/*
|
|
* Local variables:
|
|
* c-file-style: "stroustrup"
|
|
* c-file-offsets: ((case-label . *) (statement-case-intro . *))
|
|
* indent-tabs-mode: nil
|
|
* End:
|
|
*
|
|
* vim: expandtab shiftwidth=4:
|
|
*/
|
|
|