X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=wma_afh.c;h=6db79d0e9ad887256db8c6cd1f942f3bfa3bc9bd;hp=2d463900e7be81d148cd3ab6dce554d61ce3044a;hb=acebb60a3709eebbfed30dc47c1f324969e4d7c7;hpb=620c2a3eb4c3395c5be73f663435740ecd878775 diff --git a/wma_afh.c b/wma_afh.c index 2d463900..6db79d0e 100644 --- a/wma_afh.c +++ b/wma_afh.c @@ -27,30 +27,25 @@ _f + (_ba) + WMA_FRAME_SKIP < (_buf) + (_size); \ _f += (_ba) + WMA_FRAME_SKIP) +/* + * Must be called on a frame boundary, e.g. start + header_len. + * \return Frame count, superframe count via *num_superframes. + */ static int count_frames(const char *buf, int buf_size, int block_align, - long unsigned *num_superframes) + int *num_superframes) { - int count = 0, step = block_align + WMA_FRAME_SKIP; - const uint8_t *p = (uint8_t *)buf + WMA_FRAME_SKIP; + int fc = 0, sfc = 0; /* frame count, superframe count */ + const uint8_t *p; - if (buf_size <= WMA_FRAME_SKIP) { - if (num_superframes) - *num_superframes = 0; - return 0; + FOR_EACH_FRAME(p, (uint8_t *)buf, buf_size, block_align) { + fc += p[WMA_FRAME_SKIP] & 0x0f; + sfc++; } - count = 0; - step = block_align + WMA_FRAME_SKIP; - p = (uint8_t *)buf + WMA_FRAME_SKIP; - - FOR_EACH_FRAME(p, (uint8_t *)buf, buf_size, block_align) - count += p[WMA_FRAME_SKIP] & 0x0f; - PARA_DEBUG_LOG("%d frames\n", count); - if (num_superframes) { - *num_superframes = buf_size / step; - PARA_DEBUG_LOG("%lu superframes\n", *num_superframes); - } - return count; + PARA_INFO_LOG("%d frames, %d superframes\n", fc, sfc); + if (num_superframes) + *num_superframes = sfc; + return fc; } /* @@ -185,29 +180,45 @@ static void read_asf_tags(const char *buf, int buf_size, struct taginfo *ti) } +static void set_chunk_tv(int num_frames, int num_chunks, int frequency, + struct timeval *result) +{ + uint64_t x = (uint64_t)num_frames * 1000 * 1000 + / frequency / num_chunks; + + result->tv_sec = x / 1000 / 1000; + result->tv_usec = x % (1000 * 1000); + PARA_INFO_LOG("%d chunks, chunk time: %lums\n", num_chunks, + tv2ms(result)); +} + +/* Must be called on a frame boundary. */ static int wma_make_chunk_table(char *buf, size_t buf_size, int block_align, struct afh_info *afhi) { const uint8_t *f, *start = (uint8_t *)buf; - int i, j, frames_per_chunk, chunk_time; + int i, j, frames_per_chunk; size_t ct_size = 250; - int count = 0, num_frames; + int ret, count = 0, num_frames, num_superframes; afhi->chunk_table = para_malloc(ct_size * sizeof(uint32_t)); afhi->chunk_table[0] = 0; afhi->chunk_table[1] = afhi->header_len; num_frames = count_frames(buf, buf_size, block_align, - &afhi->chunks_total); - PARA_INFO_LOG("%d frames\n", num_frames); + &num_superframes); + ret = -E_NO_WMA; + if (num_frames == 0 || num_superframes == 0) + goto fail; afhi->seconds_total = num_frames * 2048 /* FIXME */ / afhi->frequency; - frames_per_chunk = num_frames / afhi->chunks_total; + frames_per_chunk = num_frames / num_superframes; + PARA_INFO_LOG("%d frames per chunk\n", frames_per_chunk); i = 0; j = 1; FOR_EACH_FRAME(f, start, buf_size, block_align) { count += f[WMA_FRAME_SKIP] & 0x0f; - while (count > j * frames_per_chunk && f > start) { + while (count > j * frames_per_chunk) { j++; if (j >= ct_size) { ct_size *= 2; @@ -215,18 +226,15 @@ static int wma_make_chunk_table(char *buf, size_t buf_size, int block_align, afhi->chunk_table, ct_size * sizeof(uint32_t)); } - PARA_DEBUG_LOG("ct[%d]: %zu\n", j, f - start); - afhi->chunk_table[j] = f - start; + afhi->chunk_table[j] = f - start + afhi->header_len + block_align + WMA_FRAME_SKIP; } } afhi->chunks_total = j; - chunk_time = num_frames * 1000 / afhi->frequency * 2048 - / afhi->chunks_total; - PARA_INFO_LOG("ct: %d\n", chunk_time); - afhi->chunk_tv.tv_sec = chunk_time / 1000; - afhi->chunk_tv.tv_usec = (chunk_time % 1000) * 1000; - //set_chunk_tv(num_frames, j, afhi->frequency, &afhi->chunk_tv); + set_chunk_tv(num_frames * 2048, j + 10 /* FIXME */, afhi->frequency, &afhi->chunk_tv); return 1; +fail: + free(afhi->chunk_table); + return ret; } static int wma_get_file_info(char *map, size_t numbytes, __a_unused int fd, @@ -238,14 +246,18 @@ static int wma_get_file_info(char *map, size_t numbytes, __a_unused int fd, ret = read_asf_header(map, numbytes, &ahi); if (ret < 0) return ret; + if (ret == 0) + return -E_NO_WMA; afhi->bitrate = ahi.bit_rate / 1000; + if (ahi.sample_rate == 0) + return -E_NO_WMA; afhi->frequency = ahi.sample_rate; afhi->channels = ahi.channels; afhi->header_len = ahi.header_len; afhi->header_offset = 0; - read_asf_tags(map, ahi.header_len, &afhi->tags); wma_make_chunk_table(map + ahi.header_len, numbytes - ahi.header_len, ahi.block_align, afhi); + read_asf_tags(map, ahi.header_len, &afhi->tags); return 0; }