diff options
Diffstat (limited to 'plugins/dca')
-rw-r--r-- | plugins/dca/Makefile.am | 1 | ||||
-rw-r--r-- | plugins/dca/convert2s16.c | 218 | ||||
-rw-r--r-- | plugins/dca/dcaplug.c | 117 |
3 files changed, 60 insertions, 276 deletions
diff --git a/plugins/dca/Makefile.am b/plugins/dca/Makefile.am index 0ae4734c..4a2b4b5a 100644 --- a/plugins/dca/Makefile.am +++ b/plugins/dca/Makefile.am @@ -8,7 +8,6 @@ gettimeofday.c\ parse.c\ bitstream.c\ downmix.c\ -convert2s16.c\ audio_out.h\ dca.h\ dts.h\ diff --git a/plugins/dca/convert2s16.c b/plugins/dca/convert2s16.c deleted file mode 100644 index b0647eae..00000000 --- a/plugins/dca/convert2s16.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * convert2s16.c - * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> - * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> - * - * This file is part of a52dec, a free ATSC A-52 stream decoder. - * See http://liba52.sourceforge.net/ for updates. - * - * a52dec 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 of the License, or - * (at your option) any later version. - * - * a52dec 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 this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "config.h" - -#include <inttypes.h> - -#include "dca.h" - -#include <stdio.h> - -#ifdef LIBDCA_DOUBLE -typedef float convert_t; -#else -typedef sample_t convert_t; -#endif - -static inline int16_t convert (int32_t i) -{ -#ifdef LIBDCA_FIXED - i >>= 15; -#else - i -= 0x43c00000; -#endif - return (i > 32767) ? 32767 : ((i < -32768) ? -32768 : i); -} - -void convert2s16_1 (convert_t * _f, int16_t * s16) -{ - int i; - int32_t * f = (int32_t *) _f; - - for (i = 0; i < 256; i++) { - s16[i] = convert (f[i]); - } -} - -void convert2s16_2 (convert_t * _f, int16_t * s16) -{ - int i; - int32_t * f = (int32_t *) _f; - - for (i = 0; i < 256; i++) { - s16[2*i] = convert (f[i]); - s16[2*i+1] = convert (f[i+256]); - } -} - -void convert2s16_3 (convert_t * _f, int16_t * s16) -{ - int i; - int32_t * f = (int32_t *) _f; - - for (i = 0; i < 256; i++) { - s16[3*i] = convert (f[i]); - s16[3*i+1] = convert (f[i+256]); - s16[3*i+2] = convert (f[i+512]); - } -} - -void convert2s16_4 (convert_t * _f, int16_t * s16) -{ - int i; - int32_t * f = (int32_t *) _f; - - for (i = 0; i < 256; i++) { - s16[4*i] = convert (f[i]); - s16[4*i+1] = convert (f[i+256]); - s16[4*i+2] = convert (f[i+512]); - s16[4*i+3] = convert (f[i+768]); - } -} - -void convert2s16_5 (convert_t * _f, int16_t * s16) -{ - int i; - int32_t * f = (int32_t *) _f; - - for (i = 0; i < 256; i++) { - s16[5*i] = convert (f[i]); - s16[5*i+1] = convert (f[i+256]); - s16[5*i+2] = convert (f[i+512]); - s16[5*i+3] = convert (f[i+768]); - s16[5*i+4] = convert (f[i+1024]); - } -} - -int channels_multi (int flags) -{ - if (flags & DCA_LFE) - return 6; - else if (flags & 1) /* center channel */ - return 5; - else if ((flags & DCA_CHANNEL_MASK) == DCA_2F2R) - return 4; - else - return 2; -} - -void convert2s16_multi (convert_t * _f, int16_t * s16, int flags) -{ - int i; - int32_t * f = (int32_t *) _f; - - switch (flags) { - case DCA_MONO: - for (i = 0; i < 256; i++) { - s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0; - s16[5*i+4] = convert (f[i]); - } - break; - case DCA_CHANNEL: - case DCA_STEREO: - case DCA_DOLBY: - convert2s16_2 (_f, s16); - break; - case DCA_3F: - for (i = 0; i < 256; i++) { - s16[5*i] = convert (f[i]); - s16[5*i+1] = convert (f[i+512]); - s16[5*i+2] = s16[5*i+3] = 0; - s16[5*i+4] = convert (f[i+256]); - } - break; - case DCA_2F2R: - convert2s16_4 (_f, s16); - break; - case DCA_3F2R: - convert2s16_5 (_f, s16); - break; - case DCA_MONO | DCA_LFE: - for (i = 0; i < 256; i++) { - s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0; - s16[6*i+4] = convert (f[i+256]); - s16[6*i+5] = convert (f[i]); - } - break; - case DCA_CHANNEL | DCA_LFE: - case DCA_STEREO | DCA_LFE: - case DCA_DOLBY | DCA_LFE: - for (i = 0; i < 256; i++) { - s16[6*i] = convert (f[i+256]); - s16[6*i+1] = convert (f[i+512]); - s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0; - s16[6*i+5] = convert (f[i]); - } - break; - case DCA_3F | DCA_LFE: - for (i = 0; i < 256; i++) { - s16[6*i] = convert (f[i+256]); - s16[6*i+1] = convert (f[i+768]); - s16[6*i+2] = s16[6*i+3] = 0; - s16[6*i+4] = convert (f[i+512]); - s16[6*i+5] = convert (f[i]); - } - break; - case DCA_2F2R | DCA_LFE: - for (i = 0; i < 256; i++) { - s16[6*i] = convert (f[i+256]); - s16[6*i+1] = convert (f[i+512]); - s16[6*i+2] = convert (f[i+768]); - s16[6*i+3] = convert (f[i+1024]); - s16[6*i+4] = 0; - s16[6*i+5] = convert (f[i]); - } - break; - case DCA_3F2R | DCA_LFE: - for (i = 0; i < 256; i++) { - s16[6*i] = convert (f[i+256]); - s16[6*i+1] = convert (f[i+768]); - s16[6*i+2] = convert (f[i+1024]); - s16[6*i+3] = convert (f[i+1280]); - s16[6*i+4] = convert (f[i+512]); - s16[6*i+5] = convert (f[i]); - } - break; - } -} - -void s16_swap (int16_t * s16, int channels) -{ - int i; - uint16_t * u16 = (uint16_t *) s16; - - for (i = 0; i < 256 * channels; i++) - u16[i] = (u16[i] >> 8) | (u16[i] << 8); -} - -void s32_swap (int32_t * s32, int channels) -{ - int i; - uint32_t * u32 = (uint32_t *) s32; - - for (i = 0; i < 256 * channels; i++) - u32[i] = (u32[i] << 24) | ((u32[i] << 8)&0xFF0000) | - ((u32[i] >> 8)&0xFF00) | (u32[i] >> 24); -} diff --git a/plugins/dca/dcaplug.c b/plugins/dca/dcaplug.c index bcd782a1..635f3c0e 100644 --- a/plugins/dca/dcaplug.c +++ b/plugins/dca/dcaplug.c @@ -73,7 +73,7 @@ static DB_decoder_t plugin; DB_functions_t *deadbeef; #define BUFFER_SIZE 24576 -#define OUT_BUFFER_SIZE 100000 // one block may be up to 22K samples, which is 88Kb for stereo +#define OUT_BUFFER_SIZE 25000 // one block may be up to 22K samples, which is 88Kb for stereo #define HEADER_SIZE 14 typedef struct { DB_fileinfo_t info; @@ -82,7 +82,6 @@ typedef struct { int startsample; int endsample; int currentsample; - int wavchannels; dca_state_t * state; int disable_adjust;// = 0; float gain;// = 1; @@ -95,7 +94,7 @@ typedef struct { int flags; int bit_rate; int frame_byte_size; - char output_buffer[OUT_BUFFER_SIZE]; + int16_t output_buffer[OUT_BUFFER_SIZE*6]; int remaining; int skipsamples; } ddb_dca_state_t; @@ -157,32 +156,35 @@ static int wav_channels (int flags, uint32_t * speaker_flags) return chans; } +static inline int16_t convert (int32_t i) +{ +#ifdef LIBDCA_FIXED + i >>= 15; +#else + i -= 0x43c00000; +#endif + return (i > 32767) ? 32767 : ((i < -32768) ? -32768 : i); +} + static int convert_samples (ddb_dca_state_t *state, int flags) { sample_t *_samples = dca_samples (state->state); - int chans, size; - uint32_t speaker_flags; - int16_t int16_samples[256*6]; - convert_t * samples = _samples; - chans = channels_multi (flags); - flags &= DCA_CHANNEL_MASK | DCA_LFE; + int samplesize = state->info.fmt.channels * state->info.fmt.bps / 8; - convert2s16_multi (samples, int16_samples, flags); + int n, i, c; + n = 256; + int16_t *dst = state->output_buffer + state->remaining * state->info.fmt.channels; - int16_t *dest = (int16_t*)(state->output_buffer + state->remaining * sizeof (int16_t) * 2); - int i; - for (i = 0; i < 256; i++) { - *dest = int16_samples[i * chans + 0]; - dest++; - *dest = int16_samples[i * chans + 1]; - dest++; + for (i = 0; i < n; i++) { + for (c = 0; c < state->info.fmt.channels; c++) { + *dst++ = convert (*((int32_t*)(_samples + 256 * c))); + } + _samples ++; } - state->remaining += 256; - //trace ("wrote %d bytes (chans=%d)\n", size, chans); - //fwrite (&ordered_samples, 1, size, out); + state->remaining += 256; return 0; } @@ -343,7 +345,7 @@ dts_open_wav (DB_FILE *fp, wavfmt_t *fmt, int64_t *totalsamples) { } static DB_fileinfo_t * -dts_open (void) { +dts_open (uint32_t hints) { DB_fileinfo_t *_info = malloc (sizeof (ddb_dca_state_t)); ddb_dca_state_t *info = (ddb_dca_state_t *)_info; memset (info, 0, sizeof (ddb_dca_state_t)); @@ -364,17 +366,15 @@ dts_init (DB_fileinfo_t *_info, DB_playItem_t *it) { int64_t totalsamples = -1; // WAV format if ((info->offset = dts_open_wav (info->file, &fmt, &totalsamples)) == -1) { - // try raw DTS @ 48KHz + // raw dts, leave detection to libdca info->offset = 0; totalsamples = -1; - info->wavchannels = 2; - _info->bps = 16; + _info->fmt.bps = 16; } else { - _info->bps = fmt.wBitsPerSample; - _info->channels = fmt.nChannels; - info->wavchannels = fmt.nChannels; - _info->samplerate = fmt.nSamplesPerSec; + _info->fmt.bps = fmt.wBitsPerSample; + _info->fmt.channels = fmt.nChannels; + _info->fmt.samplerate = fmt.nSamplesPerSec; } _info->plugin = &plugin; @@ -400,40 +400,48 @@ dts_init (DB_fileinfo_t *_info, DB_playItem_t *it) { int flags = info->flags &~ (DCA_LFE | DCA_ADJUST_LEVEL); switch (flags) { case DCA_MONO: - _info->channels = 1; + _info->fmt.channels = 1; + _info->fmt.channelmask = DDB_SPEAKER_FRONT_LEFT; break; case DCA_CHANNEL: case DCA_STEREO: case DCA_DOLBY: case DCA_STEREO_SUMDIFF: case DCA_STEREO_TOTAL: - _info->channels = 2; + _info->fmt.channels = 2; + _info->fmt.channelmask = (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT); break; case DCA_3F: case DCA_2F1R: - _info->channels = 3; + _info->fmt.channels = 3; + _info->fmt.channelmask = (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_FRONT_CENTER); break; case DCA_2F2R: case DCA_3F1R: - _info->channels = 4; + _info->fmt.channels = 4; + _info->fmt.channelmask = (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_BACK_LEFT | DDB_SPEAKER_BACK_RIGHT); break; case DCA_3F2R: - _info->channels = 5; + _info->fmt.channels = 5; + _info->fmt.channelmask = (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_BACK_LEFT | DDB_SPEAKER_BACK_RIGHT | DDB_SPEAKER_FRONT_CENTER); break; case DCA_4F2R: - _info->channels = 6; + _info->fmt.channels = 6; + _info->fmt.channelmask = (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_BACK_LEFT | DDB_SPEAKER_BACK_RIGHT | DDB_SPEAKER_SIDE_LEFT | DDB_SPEAKER_SIDE_RIGHT); break; } if (info->flags & DCA_LFE) { - _info->channels++; + _info->fmt.channelmask |= DDB_SPEAKER_LOW_FREQUENCY; + _info->fmt.channels++; } - if (!_info->channels) { + + if (!_info->fmt.channels) { trace ("dts: invalid numchannels\n"); return -1; } - _info->samplerate = info->sample_rate; + _info->fmt.samplerate = info->sample_rate; if (it->endsample > 0) { info->startsample = it->startsample; @@ -464,11 +472,12 @@ dts_free (DB_fileinfo_t *_info) { } static int -dts_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) { +dts_read (DB_fileinfo_t *_info, char *bytes, int size) { ddb_dca_state_t *info = (ddb_dca_state_t *)_info; + int samplesize = _info->fmt.channels * _info->fmt.bps / 8; if (info->endsample >= 0) { - if (info->currentsample + size / (2 * _info->channels) > info->endsample) { - size = (info->endsample - info->currentsample + 1) * 2 * _info->channels; + if (info->currentsample + size / samplesize > info->endsample) { + size = (info->endsample - info->currentsample + 1) * samplesize; if (size <= 0) { return 0; } @@ -476,30 +485,25 @@ dts_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) { } int initsize = size; - int out_channels = _info->channels; - if (out_channels > 2) { - out_channels = 2; - } - int sample_size = ((_info->bps >> 3) * out_channels); while (size > 0) { if (info->skipsamples > 0 && info->remaining > 0) { int skip = min (info->remaining, info->skipsamples); - int sample_size = _info->bps/8 * info->wavchannels; if (skip < info->remaining) { - memmove (info->output_buffer, info->output_buffer + skip * sample_size, (info->remaining - skip) * sample_size); + memmove (info->output_buffer, info->output_buffer + skip * _info->fmt.channels, (info->remaining - skip) * samplesize); } info->remaining -= skip; info->skipsamples -= skip; } if (info->remaining > 0) { - int n = size / sample_size; + int n = size / samplesize; n = min (n, info->remaining); - memcpy (bytes, info->output_buffer, n * sample_size); + memcpy (bytes, info->output_buffer, n * samplesize); + if (info->remaining > n) { - memmove (info->output_buffer, info->output_buffer + n * sample_size, (info->remaining - n) * sample_size); + memmove (info->output_buffer, info->output_buffer + n * _info->fmt.channels, (info->remaining - n) * samplesize); } - bytes += n * sample_size; - size -= n * sample_size; + bytes += n * samplesize; + size -= n * samplesize; info->remaining -= n; // trace ("dca: write %d samples\n", n); } @@ -514,7 +518,7 @@ dts_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) { } } - info->currentsample += (initsize-size) / sample_size; + info->currentsample += (initsize-size) / samplesize; deadbeef->streamer_set_bitrate (info->bit_rate/1000); return initsize-size; } @@ -532,14 +536,14 @@ dts_seek_sample (DB_fileinfo_t *_info, int sample) { info->skipsamples = sample - nframe * info->frame_length; info->currentsample = sample; - _info->readpos = (float)(sample - info->startsample) / _info->samplerate; + _info->readpos = (float)(sample - info->startsample) / _info->fmt.samplerate; return 0; } static int dts_seek (DB_fileinfo_t *_info, float time) { ddb_dca_state_t *info = (ddb_dca_state_t *)_info; - return dts_seek_sample (_info, time * _info->samplerate); + return dts_seek_sample (_info, time * _info->fmt.samplerate); } static DB_playItem_t * @@ -658,8 +662,7 @@ static DB_decoder_t plugin = { .open = dts_open, .init = dts_init, .free = dts_free, - .read_int16 = dts_read_int16, -// .read_float32 = dts_read_float32, + .read = dts_read, .seek = dts_seek, .seek_sample = dts_seek_sample, .insert = dts_insert, |