ReactOS  0.4.13-dev-249-gcba1a2f
ntom.c
Go to the documentation of this file.
1 /*
2  ntom.c: N->M down/up sampling; the setup code.
3 
4  copyright 1995-2008 by the mpg123 project - free software under the terms of the LGPL 2.1
5  see COPYING and AUTHORS files in distribution or http://mpg123.org
6  initially written by Michael Hipp
7 */
8 
9 #define SAFE_NTOM /* Do not depend on off_t*off_t with big values still being in the range... */
10 #include "mpg123lib_intern.h"
11 #include "debug.h"
12 
14 {
15  long m,n;
16  m = frame_freq(fr);
17  n = fr->af.rate;
18  if(VERBOSE2)
19  fprintf(stderr,"Init rate converter: %ld->%ld\n",m,n);
20 
21  if(n > NTOM_MAX_FREQ || m > NTOM_MAX_FREQ || m <= 0 || n <= 0) {
22  if(NOQUIET) error("NtoM converter: illegal rates");
23  fr->err = MPG123_BAD_RATE;
24  return -1;
25  }
26 
27  n *= NTOM_MUL;
28  fr->ntom_step = (unsigned long) n / m;
29 
30  if(fr->ntom_step > (unsigned long)NTOM_MAX*NTOM_MUL) {
31  if(NOQUIET) error3("max. 1:%i conversion allowed (%lu vs %lu)!", NTOM_MAX, fr->ntom_step, (unsigned long)8*NTOM_MUL);
32  fr->err = MPG123_BAD_RATE;
33  return -1;
34  }
35 
36  fr->ntom_val[0] = fr->ntom_val[1] = ntom_val(fr, fr->num);
37  return 0;
38 }
39 
40 /*
41  The SAFE_NTOM does iterative loops instead of straight multiplication.
42  The safety is not just about the algorithm closely mimicking the decoder instead of applying some formula,
43  it is more about avoiding multiplication of possibly big sample offsets (a 32bit off_t could overflow too easily).
44 */
45 
46 unsigned long ntom_val(mpg123_handle *fr, off_t frame)
47 {
48  off_t ntm;
49 #ifdef SAFE_NTOM /* Carry out the loop, without the threatening integer overflow. */
50  off_t f;
51  ntm = NTOM_MUL>>1; /* for frame 0 */
52  for(f=0; f<frame; ++f) /* for frame > 0 */
53  {
54  ntm += fr->spf*fr->ntom_step;
55  ntm -= (ntm/NTOM_MUL)*NTOM_MUL;
56  }
57 #else /* Just make one computation with overall sample offset. */
58  ntm = (NTOM_MUL>>1) + fr->spf*frame*fr->ntom_step;
59  ntm -= (ntm/NTOM_MUL)*NTOM_MUL;
60 #endif
61  return (unsigned long) ntm;
62 }
63 
64 /* Set the ntom value for next expected frame to be decoded.
65  This is for keeping output consistent across seeks. */
67 {
68  fr->ntom_val[1] = fr->ntom_val[0] = ntom_val(fr, num);
69 }
70 
71 /* Carry out the ntom sample count operation for this one frame.
72  No fear of integer overflow here. */
74 {
75  /* The do this before decoding the separate channels, so there is only one common ntom value. */
76  int ntm = fr->ntom_val[0];
77  ntm += fr->spf*fr->ntom_step;
78  return ntm/NTOM_MUL;
79 }
80 
81 /* Convert frame offset to unadjusted output sample offset. */
83 {
84 #ifdef SAFE_NTOM
85  off_t f;
86 #endif
87  off_t soff = 0;
88  off_t ntm = ntom_val(fr,0);
89 #ifdef SAFE_NTOM
90  if(frame <= 0) return 0;
91  for(f=0; f<frame; ++f)
92  {
93  ntm += fr->spf*fr->ntom_step;
94  soff += ntm/NTOM_MUL;
95  ntm -= (ntm/NTOM_MUL)*NTOM_MUL;
96  }
97 #else
98  soff = (ntm + frame*(off_t)fr->spf*(off_t)fr->ntom_step)/(off_t)NTOM_MUL;
99 #endif
100  return soff;
101 }
102 
103 /* Convert input samples to unadjusted output samples. */
105 {
106  off_t soff = 0;
107  off_t ntm = ntom_val(fr,0);
108 #ifdef SAFE_NTOM
109  {
110  off_t block = fr->spf;
111  if(ins <= 0) return 0;
112  do
113  {
114  off_t nowblock = ins > block ? block : ins;
115  ntm += nowblock*fr->ntom_step;
116  soff += ntm/NTOM_MUL;
117  ntm -= (ntm/NTOM_MUL)*NTOM_MUL;
118  ins -= nowblock;
119  } while(ins > 0);
120  }
121 #else
122  /* Beware of overflows: when off_t is 32bits, the multiplication blows too easily.
123  Of course, it blows for 64bits, too, in theory, but that's for _really_ large files. */
124  soff = ((off_t)ntm + (off_t)ins*(off_t)fr->ntom_step)/(off_t)NTOM_MUL;
125 #endif
126  return soff;
127 }
128 
129 /* Determine frame offset from unadjusted output sample offset. */
131 {
132  off_t ioff = 0; /* frames or samples */
133  off_t ntm = ntom_val(fr,0);
134 #ifdef SAFE_NTOM
135  if(soff <= 0) return 0;
136  for(ioff=0; 1; ++ioff)
137  {
138  ntm += fr->spf*fr->ntom_step;
139  if(ntm/NTOM_MUL > soff) break;
140  soff -= ntm/NTOM_MUL;
141  ntm -= (ntm/NTOM_MUL)*NTOM_MUL;
142  }
143  return ioff;
144 #else
145  ioff = (soff*(off_t)NTOM_MUL-ntm)/(off_t)fr->ntom_step;
146  return ioff/(off_t)fr->spf;
147 #endif
148 }
static unsigned int block
Definition: xmlmemory.c:118
#define error(str)
Definition: mkdosfs.c:1605
__kernel_off_t off_t
Definition: linux.h:201
GLdouble n
Definition: glext.h:7729
#define NTOM_MUL
Definition: decode.h:32
off_t ntom_frameoff(mpg123_handle *fr, off_t soff)
Definition: ntom.c:130
void ntom_set_ntom(mpg123_handle *fr, off_t num)
Definition: ntom.c:66
const GLfloat * m
Definition: glext.h:10848
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define VERBOSE2
#define off_t
Definition: dosfsck.h:5
GLfloat f
Definition: glext.h:7540
GLuint GLuint num
Definition: glext.h:9618
int synth_ntom_set_step(mpg123_handle *fr)
Definition: ntom.c:13
off_t ntom_frame_outsamples(mpg123_handle *fr)
Definition: ntom.c:73
#define NOQUIET
off_t ntom_ins2outs(mpg123_handle *fr, off_t ins)
Definition: ntom.c:104
unsigned long ntom_val(mpg123_handle *fr, off_t frame)
Definition: ntom.c:46
#define NTOM_MAX_FREQ
Definition: decode.h:31
unsigned long ntom_val[2]
Definition: frame.h:148
struct audioformat af
Definition: frame.h:266
#define NTOM_MAX
Definition: decode.h:30
#define f
Definition: ke_i.h:83
#define long
Definition: qsort.c:33
off_t ntom_frmouts(mpg123_handle *fr, off_t frame)
Definition: ntom.c:82
#define error3(s, a, b, c)
Definition: debug.h:111
FILE * stderr
unsigned long ntom_step
Definition: frame.h:149
#define frame_freq
Definition: intsym.h:229