diff options
Diffstat (limited to 'debian/transcode/transcode-1.1.7/src/audio_trans.c')
| -rw-r--r-- | debian/transcode/transcode-1.1.7/src/audio_trans.c | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/debian/transcode/transcode-1.1.7/src/audio_trans.c b/debian/transcode/transcode-1.1.7/src/audio_trans.c new file mode 100644 index 00000000..019e5212 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/src/audio_trans.c @@ -0,0 +1,176 @@ +/* + * audio_trans.c - audio frame transformation routines + * Written by Andrew Church <achurch@achurch.org> + * + * This file is part of transcode, a video stream processing tool. + * transcode is free software, distributable under the terms of the GNU + * General Public License (version 2 or later). See the file COPYING + * for details. + */ + +#include "transcode.h" +#include "framebuffer.h" +#include "audio_trans.h" +#include "libtcaudio/tcaudio.h" + +/*************************************************************************/ + +/* Handle for calling tcaudio functions. */ +static TCAHandle handle = 0; + +/*************************************************************************/ +/*************************************************************************/ + +/** + * do_process_audio: Perform actual audio processing. + * + * Parameters: + * vob: Global data pointer. + * ptr: Pointer to audio frame buffer. + * Return value: + * 1 on success, 0 on failure. + */ + +static int do_process_audio(vob_t *vob, aframe_list_t *ptr) +{ + int srcfmt, nsamples; + + /* First convert audio to destination format (also handles -d) */ + if (vob->a_bits == 8) { + srcfmt = TCA_U8; + nsamples = ptr->audio_size; + } else if (vob->a_bits == 16) { + srcfmt = pcmswap ? TCA_S16BE : TCA_S16LE; + nsamples = ptr->audio_size / 2; + } else { + tc_log_error(__FILE__, "Sorry, source audio format not supported"); + return 0; + } + tca_convert_from(handle, ptr->audio_buf, nsamples, srcfmt); + + /* Convert between stereo and mono */ + if (vob->a_chan == 1 && vob->dm_chan == 2) { + tca_mono_to_stereo(handle, ptr->audio_buf, nsamples); + nsamples *= 2; + } else if (vob->a_chan == 2 && vob->dm_chan == 1) { + nsamples /= 2; + tca_stereo_to_mono(handle, ptr->audio_buf, nsamples); + } + + /* Update audio buffer size */ + ptr->audio_size = nsamples * (vob->dm_bits/8); + + /* -s: Amplify volume */ + if (vob->volume > 0) { + int nclip = 0; + tca_amplify(handle, ptr->audio_buf, nsamples, vob->volume, &nclip); + vob->clip_count += nclip; + } + + /* --av_fine_ms: Shift audio */ + if (vob->sync_ms != 0) { + /* This is the first time here: convert time (ms) to samples. + * Note that we adjust based on the source rate */ + vob->sync_samples = (vob->sync_ms * vob->a_rate / 1000) * vob->dm_chan; + if (verbose & TC_DEBUG) { + if (vob->sync_samples < 0) { + tc_log_info(__FILE__, "inserting %d PCM samples (%d ms)", + -vob->sync_samples, -vob->sync_ms); + } else { + tc_log_info(__FILE__, "deleting %d PCM samples (%d ms)", + vob->sync_samples, vob->sync_ms); + } + } + vob->sync_ms = 0; // Clear it so we don't come here again + } + if (vob->sync_samples < 0) { + int new_samples = -vob->sync_samples; + int new_bytes = new_samples * (vob->dm_bits/8); + memmove((uint8_t *)ptr->audio_buf + new_bytes, ptr->audio_buf, + ptr->audio_size); + memset(ptr->audio_buf, 0, new_bytes); + nsamples += new_samples; + ptr->audio_size += new_bytes; + vob->sync_samples = 0; + } else if (vob->sync_samples > 0) { + int del_samples = vob->sync_samples; + if (del_samples >= nsamples) { + del_samples = nsamples; + nsamples = 0; + ptr->audio_size = 0; + } else { + int del_bytes = del_samples * (vob->dm_bits/8); + memmove(ptr->audio_buf, (uint8_t *)ptr->audio_buf + del_bytes, + ptr->audio_size - del_bytes); + nsamples -= del_samples; + ptr->audio_size -= del_bytes; + } + vob->sync_samples -= del_samples; + } + + /* All done */ + return 1; +} + +/*************************************************************************/ + +/** + * process_aud_frame: Main audio frame processing routine. + * + * Parameters: + * vob: Global data pointer. + * ptr: Pointer to audio frame buffer. + * Return value: + * 0 on success, -1 on failure. + */ + +int process_aud_frame(vob_t *vob, aframe_list_t *ptr) +{ + /* Check parameter validity */ + if (!vob || !ptr) + return -1; + + /* Allocate tcaudio handle if necessary */ + if (!handle) { + AudioFormat format; + if (vob->dm_bits == 8) { + format = TCA_U8; + } else if (vob->dm_bits == 16) { + format = TCA_S16LE; + } else { + tc_log_error(__FILE__, "Sorry, output audio format not supported"); + return -1; + } + handle = tca_init(format); + if (!handle) { + tc_log_error(__FILE__, "tca_init() failed!"); + return -1; + } + } + + /* Check for pass-through mode */ + if (vob->pass_flag & TC_AUDIO) + return 0; + + /* Check audio format */ + if (vob->im_a_codec != CODEC_PCM) { + tc_log_error(__FILE__, + "Sorry, only PCM audio is supported for processing"); + return -1; + } + + /* Actually perform processing */ + return do_process_audio(vob, ptr) ? 0 : -1; +} + +/*************************************************************************/ + +/* + * Local variables: + * c-file-style: "stroustrup" + * c-file-offsets: ((case-label . *) (statement-case-intro . *)) + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: + */ |
