ref: 2a0be2ce7ff051669f4d3693dcce30901a0181a3
parent: 5376908c4b87663126b94f7cd4b16114f6dc13fe
author: robs <robs>
date: Mon Aug 30 05:36:05 EDT 2010
AMR file duration
--- a/src/amr.h
+++ b/src/amr.h
@@ -90,6 +90,7 @@
{
int open_library_result;
+ (void)encoding;
#ifdef AMR_OPENCORE
if (AMR_OPENCORE_ENABLE_ENCODE || !encoding)
{
@@ -151,6 +152,24 @@
#endif
}
+static size_t amr_duration_frames(sox_format_t * ft)
+{
+ off_t frame_size, data_start_offset = lsx_tell(ft);
+ size_t frames;
+ uint8_t coded;
+
+ for (frames = 0; lsx_readbuf(ft, &coded, (size_t)1) == 1; ++frames) {
+ frame_size = amr_block_size[coded >> 3 & 15];
+ if (lsx_seeki(ft, frame_size - 1, SEEK_CUR)) {
+ lsx_fail("seek");
+ break;
+ }
+ }
+ lsx_debug("frames=%lu", (unsigned long)frames);
+ lsx_seeki(ft, data_start_offset, SEEK_SET);
+ return frames;
+}
+
static int startread(sox_format_t * ft)
{
priv_t * p = (priv_t *)ft->priv;
@@ -180,6 +199,8 @@
ft->signal.rate = AMR_RATE;
ft->encoding.encoding = AMR_ENCODING;
ft->signal.channels = 1;
+ ft->signal.length = ft->signal.length != SOX_IGNORE_LENGTH && ft->seekable?
+ (size_t)(amr_duration_frames(ft) * .02 * ft->signal.rate +.5) : SOX_UNSPEC;
return SOX_SUCCESS;
}