summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2013-01-25 21:36:05 +0100
committerGravatar waker <wakeroid@gmail.com>2013-01-25 21:36:05 +0100
commit1bceb2657b2e2e426c3fc1c96e668e8612fec490 (patch)
tree781534b414ffd6ec231a9737bea36f00193af07b /plugins
parent66a3c3505fabf206db8aea7cfffbd064ba21fdb1 (diff)
wma: fixed seeking of VBR files; seeking is NOT sample-accurate
Diffstat (limited to 'plugins')
-rw-r--r--plugins/wma/libasf/asf.c23
-rw-r--r--plugins/wma/wma_plugin.c14
2 files changed, 26 insertions, 11 deletions
diff --git a/plugins/wma/libasf/asf.c b/plugins/wma/libasf/asf.c
index ee07953a..90c8974f 100644
--- a/plugins/wma/libasf/asf.c
+++ b/plugins/wma/libasf/asf.c
@@ -29,8 +29,8 @@
#include "asf.h"
#include "../../deadbeef.h"
extern DB_functions_t *deadbeef;
-#define trace(...) { fprintf (stderr, __VA_ARGS__); }
-//#define trace(fmt,...)
+//#define trace(...) { fprintf (stderr, __VA_ARGS__); }
+#define trace(fmt,...)
#define DEBUGF trace
/* Read an unaligned 32-bit little endian long from buffer. */
@@ -409,23 +409,26 @@ int asf_seek(int ms, asf_waveformatex_t* wfx, DB_FILE *fp, int64_t first_frame_o
int time, duration, delta, temp, count=0;
/*estimate packet number from bitrate*/
- int initial_packet = 0;//deadbeef->ftell (fp)/wfx->packet_size;
- printf ("initial_packet=%d\n", initial_packet);
+ int64_t datasize = deadbeef->fgetlength (fp) - first_frame_offset;
+
+ int initial_packet = (deadbeef->ftell (fp) - first_frame_offset) / wfx->packet_size;
int packet_num = (((int64_t)ms)*(wfx->bitrate>>3))/wfx->packet_size/1000;
- printf ("packet_num=%d (%d * %d / %d / 1000)\n", packet_num, ms, wfx->bitrate, wfx->packet_size);
- int last_packet = deadbeef->fgetlength (fp) / wfx->packet_size;
- printf ("last_packet=%d\n", last_packet);
+ int last_packet = datasize / wfx->packet_size;
if (packet_num > last_packet) {
packet_num = last_packet;
}
/*calculate byte address of the start of that packet*/
- int packet_offset = packet_num*wfx->packet_size;
- printf ("packet_offset=%d (%d*%d)\n", packet_offset, packet_num, wfx->packet_size);
+ int64_t packet_offset = packet_num*wfx->packet_size;
+ trace ("initial_packet: %d\n", initial_packet);
+ trace ("packet_num: %d\n", packet_num);
+ trace ("last_packet: %d\n", last_packet);
+ trace ("packet_offset: %lld\n", packet_offset);
/*seek to estimated packet*/
deadbeef->fseek (fp, first_frame_offset+packet_offset, SEEK_SET);
+ int64_t pos = deadbeef->ftell (fp);
temp = ms;
while (1)
{
@@ -446,8 +449,10 @@ int asf_seek(int ms, asf_waveformatex_t* wfx, DB_FILE *fp, int64_t first_frame_o
if ((time+duration>=ms && time<=ms) || count > 10) {
DEBUGF("Found our packet! Now at %d packet\n", packet_num);
+ deadbeef->fseek (fp, pos, SEEK_SET);
return time;
} else {
+ DEBUGF("Seek again\n", packet_num);
/*seek again*/
delta = ms-time;
/*estimate new packet number from bitrate and our current position*/
diff --git a/plugins/wma/wma_plugin.c b/plugins/wma/wma_plugin.c
index 9b28d5b9..6a141dd1 100644
--- a/plugins/wma/wma_plugin.c
+++ b/plugins/wma/wma_plugin.c
@@ -187,6 +187,7 @@ wmaplug_read (DB_fileinfo_t *_info, char *bytes, int size) {
wma_decode_superframe_init(&info->wmadec, audiobuf + b * info->wfx.blockalign, info->wfx.blockalign);
int n = 0;
+ trace ("subframes: %d\n", info->wmadec.nb_frames);
for (int i=0; i < info->wmadec.nb_frames; i++)
{
int wmares = wma_decode_superframe_frame(&info->wmadec,
@@ -310,14 +311,22 @@ wmaplug_seek_sample (DB_fileinfo_t *_info, int sample) {
memset(info->wmadec.frame_out, 0, sizeof(fixed32) * MAX_CHANNELS * BLOCK_MAX_SIZE * 2);
+#if 0
+ // this only works for CBR wma
int n_subframes = info->wfx.packet_size / info->wfx.blockalign;
int frame = sample / (info->wmadec.frame_len * n_subframes);
int64_t offs = frame * info->wfx.packet_size + info->first_frame_offset;
deadbeef->fseek (info->fp, offs, SEEK_SET);
-
- info->currentsample = sample;
info->skipsamples = sample - frame * info->wmadec.frame_len * n_subframes;
+ info->currentsample = sample;
+#else
+ int res = asf_seek ((int64_t)sample * 1000 / info->wfx.rate, &info->wfx, info->fp, info->first_frame_offset);
+ info->skipsamples = 0;
+ info->currentsample = (int64_t)res * info->wfx.rate / 1000;
+#endif
+
+
_info->readpos = (float)(info->currentsample - info->startsample)/_info->fmt.samplerate;
return 0;
@@ -348,6 +357,7 @@ wmaplug_insert (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname) {
get_asf_metadata (fp, it, &wfx, &first_frame_offset);
//trace ("datalen %d, channels %d, bps %d, rate %d\n", wfx.datalen, wfx.channels, wfx.bitspersample, wfx.rate);
+ trace ("packet_size: %d, max_packet_size: %d\n", wfx.packet_size, wfx.max_packet_size);
deadbeef->fseek (fp, first_frame_offset, SEEK_SET);
int64_t l = deadbeef->fgetlength (fp);