diff options
Diffstat (limited to 'src/decoder/audiofile_plugin.c')
-rw-r--r-- | src/decoder/audiofile_plugin.c | 97 |
1 files changed, 66 insertions, 31 deletions
diff --git a/src/decoder/audiofile_plugin.c b/src/decoder/audiofile_plugin.c index f66d90dc1..18cfdda5d 100644 --- a/src/decoder/audiofile_plugin.c +++ b/src/decoder/audiofile_plugin.c @@ -17,7 +17,9 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "../decoder_api.h" +#include "config.h" +#include "decoder_api.h" +#include "audio_check.h" #include <audiofile.h> #include <af_vfs.h> @@ -45,10 +47,20 @@ static int audiofile_get_duration(const char *file) } static ssize_t -audiofile_file_read(AFvirtualfile *vfile, void *data, size_t nbytes) +audiofile_file_read(AFvirtualfile *vfile, void *data, size_t length) { struct input_stream *is = (struct input_stream *) vfile->closure; - return input_stream_read(is, data, nbytes); + GError *error = NULL; + size_t nbytes; + + nbytes = input_stream_read(is, data, length, &error); + if (nbytes == 0 && error != NULL) { + g_warning("%s", error->message); + g_error_free(error); + return -1; + } + + return nbytes; } static long @@ -78,7 +90,7 @@ audiofile_file_seek(AFvirtualfile *vfile, long offset, int is_relative) { struct input_stream *is = (struct input_stream *) vfile->closure; int whence = (is_relative ? SEEK_CUR : SEEK_SET); - if (input_stream_seek(is, offset, whence)) { + if (input_stream_seek(is, offset, whence, NULL)) { return is->offset; } else { return -1; @@ -99,17 +111,56 @@ setup_virtual_fops(struct input_stream *stream) return vf; } +static enum sample_format +audiofile_bits_to_sample_format(int bits) +{ + switch (bits) { + case 8: + return SAMPLE_FORMAT_S8; + + case 16: + return SAMPLE_FORMAT_S16; + + case 24: + return SAMPLE_FORMAT_S24_P32; + + case 32: + return SAMPLE_FORMAT_S32; + } + + return SAMPLE_FORMAT_UNDEFINED; +} + +static enum sample_format +audiofile_setup_sample_format(AFfilehandle af_fp) +{ + int fs, bits; + + afGetSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits); + if (!audio_valid_sample_format(audiofile_bits_to_sample_format(bits))) { + g_debug("input file has %d bit samples, converting to 16", + bits); + bits = 16; + } + + afSetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK, + AF_SAMPFMT_TWOSCOMP, bits); + afGetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits); + + return audiofile_bits_to_sample_format(bits); +} + static void audiofile_stream_decode(struct decoder *decoder, struct input_stream *is) { + GError *error = NULL; AFvirtualfile *vf; int fs, frame_count; AFfilehandle af_fp; - int bits; struct audio_format audio_format; float total_time; uint16_t bit_rate; - int ret, current = 0; + int ret; char chunk[CHUNK_SIZE]; enum decoder_command cmd; @@ -126,26 +177,13 @@ audiofile_stream_decode(struct decoder *decoder, struct input_stream *is) return; } - afGetSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits); - if (!audio_valid_sample_format(bits)) { - g_debug("input file has %d bit samples, converting to 16", - bits); - bits = 16; - } - - afSetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK, - AF_SAMPFMT_TWOSCOMP, bits); - afGetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits); - audio_format.bits = (uint8_t)bits; - audio_format.sample_rate = - (unsigned int)afGetRate(af_fp, AF_DEFAULT_TRACK); - audio_format.channels = - (uint8_t)afGetVirtualChannels(af_fp, AF_DEFAULT_TRACK); - - if (!audio_format_valid(&audio_format)) { - g_warning("Invalid audio format: %u:%u:%u\n", - audio_format.sample_rate, audio_format.bits, - audio_format.channels); + if (!audio_format_init_checked(&audio_format, + afGetRate(af_fp, AF_DEFAULT_TRACK), + audiofile_setup_sample_format(af_fp), + afGetVirtualChannels(af_fp, AF_DEFAULT_TRACK), + &error)) { + g_warning("%s", error->message); + g_error_free(error); afCloseFile(af_fp); return; } @@ -166,17 +204,14 @@ audiofile_stream_decode(struct decoder *decoder, struct input_stream *is) if (ret <= 0) break; - current += ret; cmd = decoder_data(decoder, NULL, chunk, ret * fs, - (float)current / - (float)audio_format.sample_rate, bit_rate, NULL); if (cmd == DECODE_COMMAND_SEEK) { - current = decoder_seek_where(decoder) * + AFframecount frame = decoder_seek_where(decoder) * audio_format.sample_rate; - afSeekFrame(af_fp, AF_DEFAULT_TRACK, current); + afSeekFrame(af_fp, AF_DEFAULT_TRACK, frame); decoder_command_finished(decoder); cmd = DECODE_COMMAND_NONE; |