/* * import_sunau.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_sunau.so" #define MOD_VERSION "v0.0.2 (2004-10-02)" #define MOD_CODEC "(audio) pcm" #include "transcode.h" static int verbose_flag = TC_QUIET; static int capability_flag = TC_CAP_PCM; #define MOD_PRE sunau #include "import_def.h" #include #include #include #include "libtc/optstr.h" static int sunau_fd = -1; int sunau_init(const char *, int, int, int); int sunau_grab(size_t, char *); int sunau_stop(void); int sunau_init(const char *audio_device, int sample_rate, int precision, int channels) { audio_info_t audio_if; int encoding; if(!strcmp(audio_device, "/dev/null") || !strcmp(audio_device, "/dev/zero")) return(0); if(precision != 8 && precision != 16) { tc_log_warn(MOD_NAME, "bits/sample must be 8 or 16"); return(1); } encoding = (precision == 8) ? AUDIO_ENCODING_ULINEAR : AUDIO_ENCODING_SLINEAR_LE; AUDIO_INITINFO(&audio_if); audio_if.record.precision = precision; audio_if.record.channels = channels; audio_if.record.sample_rate = sample_rate; audio_if.record.encoding = encoding; audio_if.mode = AUMODE_RECORD; if ((sunau_fd = open(audio_device, O_RDONLY)) < 0) { tc_log_perror(MOD_NAME, MOD_NAME "open audio device"); return(1); } if (ioctl(sunau_fd, AUDIO_SETINFO, &audio_if) < 0) { tc_log_perror(MOD_NAME, "AUDIO_SETINFO"); return(1); } if (ioctl(sunau_fd, AUDIO_GETINFO, &audio_if) < 0) { tc_log_perror(MOD_NAME, "AUDIO_GETINFO"); return(1); } if (audio_if.record.precision != precision) { tc_log_warn(MOD_NAME, "unable to initialize sample size for %s; " "tried %d, got %d", audio_device, precision, audio_if.record.precision); return(1); } if (audio_if.record.channels != channels) { tc_log_warn(MOD_NAME, "unable to initialize number of channels for %s; " "tried %d, got %d", audio_device, channels, audio_if.record.channels); return(1); } if (audio_if.record.sample_rate != sample_rate) { tc_log_warn(MOD_NAME, "unable to initialize rate for %s; " "tried %d, got %d\n", audio_device, sample_rate, audio_if.record.sample_rate); return(1); } if (audio_if.record.encoding != encoding) { tc_log_warn(MOD_NAME, "unable to initialize encoding for %s; " "tried %d, got %d", audio_device, encoding, audio_if.record.encoding); return(1); } if (ioctl(sunau_fd, AUDIO_FLUSH) < 0) { tc_log_perror(MOD_NAME, "AUDIO_FLUSH"); return(1); } return(0); } int sunau_grab(size_t size, char *buffer) { int left; int offset; int received; for (left = size, offset = 0; left > 0;) { received = read(sunau_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, MOD_NAME "audio grab"); return(1); } } if (received > left) { tc_log_warn(MOD_NAME, "read returns more bytes than requested; " "requested: %d, returned: %d", left, received); return(1); } offset += received; left -= received; } return(0); } int sunau_stop(void) { close(sunau_fd); sunau_fd = -1; if (verbose_flag & TC_STATS) { tc_log_warn(MOD_NAME, "totals: (not implemented)"); } return(0); } /* ------------------------------------------------------------ * * open stream * * ------------------------------------------------------------*/ MOD_open { int ret = TC_IMPORT_OK; switch (param->flag) { case TC_VIDEO: tc_log_warn(MOD_NAME, "unsupported request (init video)\n"); ret = TC_IMPORT_ERROR; break; case TC_AUDIO: if (verbose_flag & TC_DEBUG) { tc_log_info(MOD_NAME, "sunau audio grabbing\n"); } if (sunau_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); } /* ------------------------------------------------------------ * * decode stream * * ------------------------------------------------------------*/ 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 (sunau_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); } /* ------------------------------------------------------------ * * close stream * * ------------------------------------------------------------*/ 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: sunau_stop(); break; default: tc_log_warn(MOD_NAME, "unsupported request (close)"); ret = TC_IMPORT_ERROR; break; } return(ret); }