diff options
author | waker <wakeroid@gmail.com> | 2010-11-24 22:52:07 +0100 |
---|---|---|
committer | waker <wakeroid@gmail.com> | 2010-11-24 22:52:07 +0100 |
commit | 6ca06a612a349229bc61cc811284fd51cadfe7bf (patch) | |
tree | 4a9ce0a18bb36968a5589bafeef81be517e1e24d /plugins | |
parent | 9aa1f87dbdd01832e7e4d65fecb72222f8e890d4 (diff) |
ported flac plugin to new API
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/flac/flac.c | 134 |
1 files changed, 74 insertions, 60 deletions
diff --git a/plugins/flac/flac.c b/plugins/flac/flac.c index 1de1f443..f427ef1c 100644 --- a/plugins/flac/flac.c +++ b/plugins/flac/flac.c @@ -104,24 +104,52 @@ cflac_write_callback (const FLAC__StreamDecoder *decoder, const FLAC__Frame *fra if (info->bitrate > 0) { deadbeef->streamer_set_bitrate (info->bitrate); } + int samplesize = _info->fmt.channels * _info->fmt.bps / 8; int bufsize = BUFFERSIZE - info->remaining; - int bufsamples = bufsize / (_info->channels * _info->bps / 8); + int bufsamples = bufsize / samplesize; int nsamples = min (bufsamples, frame->header.blocksize); char *bufptr = &info->buffer[info->remaining]; - float mul = 1.f/ ((1 << (_info->bps-1))-1); - int channels = _info->channels; - if (channels > 2) { - channels = 2; - } - int readbytes = frame->header.blocksize * channels * _info->bps / 8; + int readbytes = frame->header.blocksize * samplesize; - for (int i = 0; i < nsamples; i++) { - for (int c = 0; c < channels; c++) { - int32_t sample = inputbuffer[c][i]; - *((float*)bufptr) = sample * mul; - bufptr += sizeof (float); - info->remaining += sizeof (float); + if (_info->fmt.bps == 32) { + for (int i = 0; i < nsamples; i++) { + for (int c = 0; c < _info->fmt.channels; c++) { + int32_t sample = inputbuffer[c][i]; + *((int32_t*)bufptr) = sample; + bufptr += 4; + info->remaining += 4; + } + } + } + else if (_info->fmt.bps == 24) { + for (int i = 0; i < nsamples; i++) { + for (int c = 0; c < _info->fmt.channels; c++) { + int32_t sample = inputbuffer[c][i]; + *bufptr++ = sample&0xff; + *bufptr++ = (sample&0xff00)>>8; + *bufptr++ = (sample&0xff0000)>>16; + info->remaining += 3; + } + } + } + else if (_info->fmt.bps == 16) { + for (int i = 0; i < nsamples; i++) { + for (int c = 0; c < _info->fmt.channels; c++) { + int32_t sample = inputbuffer[c][i]; + *bufptr++ = sample&0xff; + *bufptr++ = (sample&0xff00)>>8; + info->remaining += 2; + } + } + } + else if (_info->fmt.bps == 8) { + for (int i = 0; i < nsamples; i++) { + for (int c = 0; c < _info->fmt.channels; c++) { + int32_t sample = inputbuffer[c][i]; + *bufptr++ = sample&0xff; + info->remaining += 1; + } } } if (readbytes > bufsize) { @@ -136,9 +164,10 @@ cflac_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMe DB_fileinfo_t *_info = (DB_fileinfo_t *)client_data; flac_info_t *info = (flac_info_t *)_info; info->totalsamples = metadata->data.stream_info.total_samples; - _info->samplerate = metadata->data.stream_info.sample_rate; - _info->channels = metadata->data.stream_info.channels; - _info->bps = metadata->data.stream_info.bits_per_sample; + _info->fmt.samplerate = metadata->data.stream_info.sample_rate; + _info->fmt.channels = metadata->data.stream_info.channels; + _info->fmt.bps = metadata->data.stream_info.bits_per_sample; + _info->fmt.channelmask = _info->fmt.channels == 1 ? DDB_SPEAKER_FRONT_LEFT : (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT); } @@ -164,7 +193,7 @@ cflac_init_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecode } static DB_fileinfo_t * -cflac_open (void) { +cflac_open (uint32_t hints) { DB_fileinfo_t *_info = malloc (sizeof (flac_info_t)); memset (_info, 0, sizeof (flac_info_t)); return _info; @@ -237,7 +266,7 @@ cflac_init (DB_fileinfo_t *_info, DB_playItem_t *it) { trace ("cflac_init bad decoder status\n"); return -1; } - //_info->samplerate = -1; + //_info->fmt.samplerate = -1; if (!FLAC__stream_decoder_process_until_end_of_metadata (info->decoder)) { trace ("cflac_init metadata failed\n"); return -1; @@ -247,7 +276,7 @@ cflac_init (DB_fileinfo_t *_info, DB_playItem_t *it) { _info->plugin = &plugin; _info->readpos = 0; - if (_info->samplerate <= 0) { // not a FLAC stream + if (_info->fmt.samplerate <= 0) { // not a FLAC stream fprintf (stderr, "corrupted/invalid flac stream\n"); return -1; } @@ -260,7 +289,7 @@ cflac_init (DB_fileinfo_t *_info, DB_playItem_t *it) { fsize -= position; } FLAC__uint64 flac_totalsamples = FLAC__stream_decoder_get_total_samples (info->decoder); - float sec = flac_totalsamples / _info->samplerate; + float sec = flac_totalsamples / _info->fmt.samplerate; if (sec > 0) { info->bitrate = fsize / sec * 8 / 1000; } @@ -309,48 +338,31 @@ cflac_free (DB_fileinfo_t *_info) { } static int -cflac_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) { +cflac_read (DB_fileinfo_t *_info, char *bytes, int size) { flac_info_t *info = (flac_info_t *)_info; - if (size / (2 * _info->channels) + info->currentsample > info->endsample) { - size = (info->endsample - info->currentsample + 1) * 2 * _info->channels; + int samplesize = _info->fmt.channels * _info->fmt.bps / 8; + if (size / samplesize + info->currentsample > info->endsample) { + size = (info->endsample - info->currentsample + 1) * samplesize; trace ("size truncated to %d bytes, cursample=%d, endsample=%d\n", size, info->currentsample, info->endsample); if (size <= 0) { return 0; } } - int n_output_channels = _info->channels; - if (n_output_channels > 2) { - n_output_channels = 2; - } int initsize = size; do { if (info->remaining) { - int n_input_frames = info->remaining / sizeof (float) / n_output_channels; - int n_output_frames = size / n_output_channels / sizeof (int16_t); - int n = min (n_input_frames, n_output_frames); + int sz = min(size, info->remaining); + memcpy (bytes, info->buffer, sz); -// trace ("flac: [1] if=%d, of=%d, n=%d, rem=%d, size=%d\n", n_input_frames, n_output_frames, n, info->remaining, size); - // convert from float to int16 - float *in = (float *)info->buffer; - for (int i = 0; i < n; i++) { - *((int16_t *)bytes) = (int16_t)((*in) * 0x7fff); - size -= sizeof (int16_t); - bytes += sizeof (int16_t); - if (n_output_channels == 2) { - *((int16_t *)bytes) = (int16_t)((*(in+1)) * 0x7fff); - size -= sizeof (int16_t); - bytes += sizeof (int16_t); - } - in += n_output_channels; - } - int sz = n * sizeof (float) * n_output_channels; + size -= sz; + bytes += sz; if (sz < info->remaining) { memmove (info->buffer, &info->buffer[sz], info->remaining - sz); } info->remaining -= sz; - info->currentsample += n; - _info->readpos += (float)n / _info->samplerate; -// trace ("flac: [2] if=%d, of=%d, n=%d, rem=%d, size=%d\n", n_input_frames, n_output_frames, n, info->remaining, size); + int n = sz / samplesize; + info->currentsample += sz / samplesize; + _info->readpos += (float)n / _info->fmt.samplerate; } if (!size) { break; @@ -372,17 +384,18 @@ cflac_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) { return initsize - size; } +#if 0 static int cflac_read_float32 (DB_fileinfo_t *_info, char *bytes, int size) { flac_info_t *info = (flac_info_t *)_info; - if (size / (4 * _info->channels) + info->currentsample > info->endsample) { - size = (info->endsample - info->currentsample + 1) * 4 * _info->channels; + if (size / (4 * _info->fmt.channels) + info->currentsample > info->endsample) { + size = (info->endsample - info->currentsample + 1) * 4 * _info->fmt.channels; trace ("size truncated to %d bytes, cursample=%d, endsample=%d\n", size, info->currentsample, info->endsample); if (size <= 0) { return 0; } } - int n_output_channels = _info->channels; + int n_output_channels = _info->fmt.channels; if (n_output_channels > 2) { n_output_channels = 2; } @@ -411,7 +424,7 @@ cflac_read_float32 (DB_fileinfo_t *_info, char *bytes, int size) { } info->remaining -= sz; info->currentsample += n; - _info->readpos += (float)n / _info->samplerate; + _info->readpos += (float)n / _info->fmt.samplerate; } if (!size) { break; @@ -432,6 +445,7 @@ cflac_read_float32 (DB_fileinfo_t *_info, char *bytes, int size) { return initsize - size; } +#endif static int cflac_seek_sample (DB_fileinfo_t *_info, int sample) { @@ -442,13 +456,13 @@ cflac_seek_sample (DB_fileinfo_t *_info, int sample) { if (!FLAC__stream_decoder_seek_absolute (info->decoder, (FLAC__uint64)(sample))) { return -1; } - _info->readpos = (float)(sample - info->startsample)/ _info->samplerate; + _info->readpos = (float)(sample - info->startsample)/ _info->fmt.samplerate; return 0; } static int cflac_seek (DB_fileinfo_t *_info, float time) { - return cflac_seek_sample (_info, time * _info->samplerate); + return cflac_seek_sample (_info, time * _info->fmt.samplerate); } static FLAC__StreamDecoderWriteStatus @@ -509,8 +523,8 @@ cflac_init_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__Str //it->tracknum = 0; if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) { trace ("flac: samplerate=%d, channels=%d\n", metadata->data.stream_info.sample_rate, metadata->data.stream_info.channels); - _info->samplerate = metadata->data.stream_info.sample_rate; - _info->channels = metadata->data.stream_info.channels; + _info->fmt.samplerate = metadata->data.stream_info.sample_rate; + _info->fmt.channels = metadata->data.stream_info.channels; info->totalsamples = metadata->data.stream_info.total_samples; deadbeef->pl_set_item_duration (it, metadata->data.stream_info.total_samples / (float)metadata->data.stream_info.sample_rate); } @@ -653,7 +667,7 @@ cflac_insert (DB_playItem_t *after, const char *fname) { // try embedded cue const char *cuesheet = deadbeef->pl_find_meta (it, "cuesheet"); if (cuesheet) { - DB_playItem_t *last = deadbeef->pl_insert_cue_from_buffer (after, it, cuesheet, strlen (cuesheet), info.totalsamples, info.info.samplerate); + DB_playItem_t *last = deadbeef->pl_insert_cue_from_buffer (after, it, cuesheet, strlen (cuesheet), info.totalsamples, info.info.fmt.samplerate); if (last) { deadbeef->pl_item_unref (it); deadbeef->pl_item_unref (last); @@ -662,7 +676,7 @@ cflac_insert (DB_playItem_t *after, const char *fname) { } // try external cue - DB_playItem_t *cue_after = deadbeef->pl_insert_cue (after, it, info.totalsamples, info.info.samplerate); + DB_playItem_t *cue_after = deadbeef->pl_insert_cue (after, it, info.totalsamples, info.info.fmt.samplerate); if (cue_after) { if (info.file) { deadbeef->fclose (info.file); @@ -849,8 +863,8 @@ static DB_decoder_t plugin = { .open = cflac_open, .init = cflac_init, .free = cflac_free, - .read_int16 = cflac_read_int16, - .read_float32 = cflac_read_float32, + .read = cflac_read, +// .read_float32 = cflac_read_float32, .seek = cflac_seek, .seek_sample = cflac_seek_sample, .insert = cflac_insert, |