annotate decoders/mpglib/layer1.c @ 474:c66080364dff

Most decoders now report total sample play time, now. Technically, this breaks binary compatibility with the 1.0 branch, since it extends the Sound_Sample struct, but most (all?) programs are just passing pointers allocated by SDL_sound around, and might be okay. Source-level compatibility is not broken...yet! :) --ryan. -------- Original Message -------- Subject: SDL_sound patch: Finding total length of time of sound file. Date: Sun, 26 Jan 2003 09:31:17 -0800 (PST) Hi Ryan, I am working with Eric Wing and helping him modify SDL_sound. AS part of our efforts in improving and enhancing SDL_sound, we like to submit this patch. We modified the codecs to find the total time of a sound file. Below is the explanation of the patch. The patch is appended as an attachment to this email. * MOTIVATION: We needed the ability to get the total play time of a sample (And we noticed that we're not the only ones). Since SDL_sound blocks direct access to the specific decoders, there is no way for a user to know this information short of decoding the whole thing. Because of this, we believe this will be a useful addition, even though the accuracy may not be perfect (subject to each decoder) or the information may not always be available. * CONTRIBUTORS: Wesley Leong (modified the majority of the codecs and verified the results) Eric Wing (showed everyone how to do modify codec, modified mikmod) Wang Lam (modified a handful of codecs, researched into specs and int overflow) Ahilan Anantha (modified a few codecs and helped with integer math) * GENERAL ISSUES: We chose the value to be milliseconds as an Sint32. Milliseconds because that's what Sound_Seek takes as a parameter and -1 to allow for instances/codecs where the value could not be determined. We are not sure if this is the final convention you want, so we are willing to work with you on this. We also expect the total_time field to be set on open and never again modified by SDL_sound. Users may access it directly much like the sample buffer and buffer_size. We thought about recomputing the time on DecodeAll, but since users may seek or decode small chunks first, not all the data may be there. So this is better done by the user. This may be good information to document. Currently, all the main codecs are implemented except for QuickTime.
author Ryan C. Gordon <icculus@icculus.org>
date Sat, 08 May 2004 08:19:50 +0000
parents ad4c8f34136a
children
rev   line source
261
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
1 /*
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
2 * Mpeg Layer-1 audio decoder
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
3 * --------------------------
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
4 * copyright (c) 1995 by Michael Hipp, All rights reserved. See also 'README'
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
5 * near unoptimzed ...
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
6 *
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
7 * may have a few bugs after last optimization ...
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
8 *
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
9 */
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
10
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
11 #include "mpg123_sdlsound.h"
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
12
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
13 void I_step_one(unsigned int balloc[], unsigned int scale_index[2][SBLIMIT],struct frame *fr)
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
14 {
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
15 unsigned int *ba=balloc;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
16 unsigned int *sca = (unsigned int *) scale_index;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
17
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
18 if(fr->stereo) {
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
19 int i;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
20 int jsbound = fr->jsbound;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
21 for (i=0;i<jsbound;i++) {
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
22 *ba++ = getbits(4);
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
23 *ba++ = getbits(4);
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
24 }
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
25 for (i=jsbound;i<SBLIMIT;i++)
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
26 *ba++ = getbits(4);
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
27
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
28 ba = balloc;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
29
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
30 for (i=0;i<jsbound;i++) {
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
31 if ((*ba++))
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
32 *sca++ = getbits(6);
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
33 if ((*ba++))
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
34 *sca++ = getbits(6);
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
35 }
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
36 for (i=jsbound;i<SBLIMIT;i++)
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
37 if ((*ba++)) {
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
38 *sca++ = getbits(6);
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
39 *sca++ = getbits(6);
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
40 }
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
41 }
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
42 else {
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
43 int i;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
44 for (i=0;i<SBLIMIT;i++)
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
45 *ba++ = getbits(4);
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
46 ba = balloc;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
47 for (i=0;i<SBLIMIT;i++)
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
48 if ((*ba++))
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
49 *sca++ = getbits(6);
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
50 }
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
51 }
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
52
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
53 void I_step_two(real fraction[2][SBLIMIT],unsigned int balloc[2*SBLIMIT],
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
54 unsigned int scale_index[2][SBLIMIT],struct frame *fr)
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
55 {
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
56 int i,n;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
57 int smpb[2*SBLIMIT]; /* values: 0-65535 */
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
58 int *sample;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
59 register unsigned int *ba;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
60 register unsigned int *sca = (unsigned int *) scale_index;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
61
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
62 if(fr->stereo) {
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
63 int jsbound = fr->jsbound;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
64 register real *f0 = fraction[0];
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
65 register real *f1 = fraction[1];
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
66 ba = balloc;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
67 for (sample=smpb,i=0;i<jsbound;i++) {
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
68 if ((n = *ba++))
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
69 *sample++ = getbits(n+1);
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
70 if ((n = *ba++))
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
71 *sample++ = getbits(n+1);
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
72 }
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
73 for (i=jsbound;i<SBLIMIT;i++)
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
74 if ((n = *ba++))
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
75 *sample++ = getbits(n+1);
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
76
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
77 ba = balloc;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
78 for (sample=smpb,i=0;i<jsbound;i++) {
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
79 if((n=*ba++))
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
80 *f0++ = (real) ( ((-1)<<n) + (*sample++) + 1) * muls[n+1][*sca++];
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
81 else
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
82 *f0++ = 0.0;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
83 if((n=*ba++))
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
84 *f1++ = (real) ( ((-1)<<n) + (*sample++) + 1) * muls[n+1][*sca++];
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
85 else
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
86 *f1++ = 0.0;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
87 }
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
88 for (i=jsbound;i<SBLIMIT;i++) {
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
89 if ((n=*ba++)) {
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
90 real samp = ( ((-1)<<n) + (*sample++) + 1);
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
91 *f0++ = samp * muls[n+1][*sca++];
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
92 *f1++ = samp * muls[n+1][*sca++];
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
93 }
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
94 else
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
95 *f0++ = *f1++ = 0.0;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
96 }
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
97 }
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
98 else {
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
99 register real *f0 = fraction[0];
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
100 ba = balloc;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
101 for (sample=smpb,i=0;i<SBLIMIT;i++)
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
102 if ((n = *ba++))
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
103 *sample++ = getbits(n+1);
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
104 ba = balloc;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
105 for (sample=smpb,i=0;i<SBLIMIT;i++) {
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
106 if((n=*ba++))
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
107 *f0++ = (real) ( ((-1)<<n) + (*sample++) + 1) * muls[n+1][*sca++];
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
108 else
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
109 *f0++ = 0.0;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
110 }
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
111 }
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
112 }
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
113
281
ad4c8f34136a Minor formatting updates.
Ryan C. Gordon <icculus@icculus.org>
parents: 279
diff changeset
114 int do_layer1(struct frame *fr,unsigned char *pcm_sample,
ad4c8f34136a Minor formatting updates.
Ryan C. Gordon <icculus@icculus.org>
parents: 279
diff changeset
115 int *pcm_point,struct mpstr *mp)
261
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
116 {
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
117 int clip=0;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
118 int i,stereo = fr->stereo;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
119 unsigned int balloc[2*SBLIMIT];
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
120 unsigned int scale_index[2][SBLIMIT];
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
121 real fraction[2][SBLIMIT];
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
122 int single = fr->single;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
123
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
124 fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ? (fr->mode_ext<<2)+4 : 32;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
125
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
126 if(stereo == 1 || single == 3)
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
127 single = 0;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
128
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
129 I_step_one(balloc,scale_index,fr);
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
130
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
131 for (i=0;i<SCALE_BLOCK;i++)
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
132 {
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
133 I_step_two(fraction,balloc,scale_index,fr);
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
134
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
135 if(single >= 0) {
279
52b9f37998db Removed global state variable; should be thread safe now.
Ryan C. Gordon <icculus@icculus.org>
parents: 261
diff changeset
136 clip += synth_1to1_mono( (real*)fraction[single],pcm_sample,pcm_point,mp);
261
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
137 }
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
138 else {
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
139 int p1 = *pcm_point;
279
52b9f37998db Removed global state variable; should be thread safe now.
Ryan C. Gordon <icculus@icculus.org>
parents: 261
diff changeset
140 clip += synth_1to1( (real*)fraction[0],0,pcm_sample,&p1,mp);
52b9f37998db Removed global state variable; should be thread safe now.
Ryan C. Gordon <icculus@icculus.org>
parents: 261
diff changeset
141 clip += synth_1to1( (real*)fraction[1],1,pcm_sample,pcm_point,mp);
261
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
142 }
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
143 }
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
144
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
145 return clip;
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
146 }
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
147
9b6e82f7c853 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
148