From 6af58c42136a609eecbc44598f27fb92197e95b2 Mon Sep 17 00:00:00 2001 From: Alexey Yakovenko Date: Tue, 1 Jun 2010 21:16:22 +0200 Subject: sample-accurate seeking --- plugins/tta/ttadec.c | 13 +++++++++---- plugins/tta/ttadec.h | 3 +-- plugins/tta/ttaplug.c | 18 +++++++++++++----- 3 files changed, 23 insertions(+), 11 deletions(-) (limited to 'plugins/tta') diff --git a/plugins/tta/ttadec.c b/plugins/tta/ttadec.c index 6eb9d6aa..6610acf7 100644 --- a/plugins/tta/ttadec.c +++ b/plugins/tta/ttadec.c @@ -380,8 +380,11 @@ static void seek_table_init (unsigned int *seek_table, } } -int set_position (tta_info *info, unsigned int pos) { - unsigned int seek_pos; +int set_position (tta_info *info, unsigned int _pos) { + // pos: seek position = seek_time_ms / SEEK_STEP +// int pos = _pos / SEEK_STEP * 1000 / info->SAMPLERATE; + int pos = _pos / info->framelen; + unsigned int seek_pos; if (pos >= info->fframes) return 0; if (!info->st_state) { @@ -401,7 +404,9 @@ int set_position (tta_info *info, unsigned int pos) { // init bit reader init_buffer_read(info); - return 0; + trace ("seek to sample %d, skip %d (%d - %d * %d)\n", _pos, _pos - pos * info->FRAMELEN, _pos, pos, info->FRAMELEN); + + return _pos - pos * info->FRAMELEN; } int player_init (tta_info *info) { @@ -598,7 +603,7 @@ static unsigned int unpack_sint32 (const char *ptr) { static int skip_id3_tag (tta_info *info) { int id3v2_size = deadbeef->junk_get_leading_size (info->HANDLE); - printf ("id3v2_size: %d\n", id3v2_size); + trace ("id3v2_size: %d\n", id3v2_size); if (id3v2_size < 0) { id3v2_size = 0; deadbeef->rewind (info->HANDLE); diff --git a/plugins/tta/ttadec.h b/plugins/tta/ttadec.h index 0e39389b..97064c34 100644 --- a/plugins/tta/ttadec.h +++ b/plugins/tta/ttadec.h @@ -134,7 +134,6 @@ typedef struct { #define READ_ERROR 5 // Can't read from file #define MEMORY_ERROR 6 // Insufficient memory available -#define FRAME_TIME 1.04489795918367346939 #define SEEK_STEP (int)(FRAME_TIME * 1000) #define ISO_BUFFER_LENGTH (1024*32) @@ -195,7 +194,7 @@ void close_tta_file ( // FUNCTION: closes currently playing file int set_position ( // FUNCTION: sets playback position tta_info *info, // tta context - unsigned int pos); // seek position = seek_time_ms / SEEK_STEP + unsigned int pos); // sample number /* * RETURN VALUE * This function returns 0 if success. Otherwise, -1 is returned diff --git a/plugins/tta/ttaplug.c b/plugins/tta/ttaplug.c index e9a3bec3..d3650324 100644 --- a/plugins/tta/ttaplug.c +++ b/plugins/tta/ttaplug.c @@ -45,6 +45,7 @@ typedef struct { int endsample; char buffer[PCM_BUFFER_LENGTH * MAX_BSIZE * MAX_NCH]; int remaining; + int samples_to_skip; } tta_info_t; static DB_fileinfo_t * @@ -115,6 +116,14 @@ tta_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) { int sample_size = ((_info->bps >> 3) * out_channels); while (size > 0) { + if (info->samples_to_skip > 0 && info->remaining > 0) { + int skip = min (info->remaining, info->samples_to_skip); + if (skip < info->remaining) { + memmove (info->buffer, info->buffer + skip * info->tta.BSIZE * info->tta.NCH, (info->remaining - skip) * info->tta.BSIZE * info->tta.NCH); + } + info->remaining -= skip; + info->samples_to_skip -= skip; + } if (info->remaining > 0) { int n = size / sample_size; n = min (n, info->remaining); @@ -132,7 +141,7 @@ tta_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) { p += info->tta.NCH * info->tta.BSIZE; } if (info->remaining > nn) { - memmove (info->buffer, p, (info->remaining - nn) * sizeof (float) * _info->channels); + memmove (info->buffer, p, (info->remaining - nn) * info->tta.BSIZE * info->tta.NCH); } info->remaining -= nn; } @@ -151,15 +160,14 @@ tta_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) { static int tta_seek_sample (DB_fileinfo_t *_info, int sample) { tta_info_t *info = (tta_info_t *)_info; - int seek_time = (sample + info->startsample) / SEEK_STEP * 1000 / info->tta.SAMPLERATE; - if (set_position (&info->tta, seek_time) != 0) { + info->samples_to_skip = set_position (&info->tta, sample + info->startsample); + if (info->samples_to_skip < 0) { fprintf (stderr, "tta: seek failed\n"); return -1; } - sample = (seek_time * SEEK_STEP) / 1000 * info->tta.SAMPLERATE; - info->currentsample = sample - info->startsample; + info->currentsample = sample; _info->readpos = sample / _info->samplerate; return 0; } -- cgit v1.2.3