1 /*-------------- Telecommunications & Signal Processing Lab ---------------
2                              McGill University
3 
4 Routine:
5   long int AOnFrame (AFILE *AFp[], const struct AO_FIpar FI[], int Nifiles,
6                      long int Nframe)
7 
8 Purpose:
9   Find the number of sample frames
10 
11 Description:
12   This routine determines the frame limits for a set of input files.  The
13   frame limits can be determined in a number of ways.
14     Nframe - Number of output frames.  If the number of frames is
15       AF_NFRAME_UNDEF, this value is undefined.
16     FI[i].Lim  - Frame limits for each input file.  The limits consist of two
17       values: the start frame and the end frame.  If the end frame is set to
18       AO_LIM_UNDEF, then the end frame is undefined.
19     AFp[i]->Nsamp - Number of samples in the input file.  If this value is
20       AF_NSAMP_UNDEF, this value is undefined.
21 
22   1: If the number of sample frames (Nframe) is specified, this value is used.
23   2: If the frame limits are specified, the number of frames is determined
24      from the maximum number of frames specified for any one file.
25   3: The number of frames is determined from the maximum of the number of
26      frames in the input files.
27 
28 Parameters:
29   <-  long int AOnFrame
30       Number of sample frames (AF_NFRAME_UNDEF if not defined)
31    -> AFILE *AFp[]
32       Array of Nifiles input audio file pointers
33    -> const struct AO_FIpar FI[]
34       Input file parameters
35    -> int Nifiles
36       Number of input files
37    -> long int Nframe
38       Number of frames.  If this value is AF_NFRAME_UNDEF, it is not used.
39 
40 Author / revision:
41   P. Kabal  Copyright (C) 2003
42   $Revision: 1.9 $  $Date: 2003/05/09 12:32:37 $
43 
44 -------------------------------------------------------------------------*/
45 
46 #include <libtsp.h>
47 #include <AO.h>
48 
49 #define MAXV(a, b)	(((a) > (b)) ? (a) : (b))
50 #define ICEILV(n, m)	(((n) + ((m) - 1)) / (m))	/* int n,m >= 0 */
51 
52 #define ROUTINE		"AOnFrame"
53 #define PGM		((UTgetProg ())[0] == '\0' ? ROUTINE : UTgetProg ())
54 
55 static long int
56 AO_NframeAF (AFILE *AFp[], const struct AO_FIpar FI[], int Nifiles);
57 static long int
58 AO_NframeFI (const struct AO_FIpar FI[], int Nifiles);
59 
60 
61 long int
AOnFrame(AFILE * AFp[],const struct AO_FIpar FI[],int Nifiles,long int Nframe)62 AOnFrame (AFILE *AFp[], const struct AO_FIpar FI[], int Nifiles,
63 	  long int Nframe)
64 
65 {
66   long int NframeT;
67 
68   if (Nframe != AF_NFRAME_UNDEF)
69     NframeT = Nframe;
70 
71   else {
72     NframeT = AO_NframeFI (FI, Nifiles);
73     if (NframeT == AF_NFRAME_UNDEF)
74       NframeT = AO_NframeAF (AFp, FI, Nifiles);
75   }
76 
77   return NframeT;
78 }
79 
80 /* Find the number of sample frames (maximum of limits) */
81 
82 
83 static long int
AO_NframeFI(const struct AO_FIpar FI[],int Nifiles)84 AO_NframeFI (const struct AO_FIpar FI[], int Nifiles)
85 
86 {
87   int i, DiffN, NotAllLim;
88   long int Nframe, Nfri;
89 
90 /*
91   - Nfri - number of frames for file i
92   - Nframe - max number of frames
93   - DiffN - true if Nframe and Nfri differ
94 */
95   DiffN = 0;
96   NotAllLim = 0;
97   Nframe = AF_NFRAME_UNDEF;
98   for (i = 0; i < Nifiles; ++i) {
99     if (FI[i].Lim[1] != AO_LIM_UNDEF)
100       Nfri = MAXV (FI[i].Lim[1] - FI[i].Lim[0] + 1L, 0L);
101     else
102       Nfri = AF_NFRAME_UNDEF;
103 
104     if (i > 0 && Nframe != Nfri) {
105       if (Nframe == AF_NFRAME_UNDEF || Nfri == AF_NFRAME_UNDEF)
106 	NotAllLim = 1;
107       else
108 	DiffN = 1;
109     }
110 
111     if (Nframe == AF_NFRAME_UNDEF)
112       Nframe = Nfri;
113     else if (Nfri != AF_NFRAME_UNDEF)
114       Nframe = MAXV (Nframe, Nfri);
115   }
116 
117   if (NotAllLim)
118     UTwarn ("%s - %s", PGM, AOM_NotAllLim);
119   else if (DiffN)
120     UTwarn ("%s - %s", PGM, AOM_DiffLim);
121 
122   return Nframe;
123 }
124 
125 /* Get the number of frames from the number of samples in the input files */
126 
127 
128 static long int
AO_NframeAF(AFILE * AFp[],const struct AO_FIpar FI[],int Nifiles)129 AO_NframeAF (AFILE *AFp[], const struct AO_FIpar FI[], int Nifiles)
130 
131 {
132   int i, DiffN;
133   long int Nframe, Nfri;
134 
135   DiffN = 0;
136   Nframe = 0L;
137   for (i = 0; i < Nifiles; ++i) {
138     if (AFp[i]->Nsamp == AF_NSAMP_UNDEF) {
139       Nframe = AF_NFRAME_UNDEF;
140       break;
141     }
142     Nfri = ICEILV (AFp[i]->Nsamp, AFp[i]->Nchan) - FI[i].Lim[0];
143     if (i > 0 && Nframe != Nfri)
144       DiffN = 1;
145     Nframe = MAXV (Nframe, Nfri);
146   }
147 
148   if (Nifiles > 1 && Nframe == AF_NFRAME_UNDEF)
149     UTwarn ("%s - %s", PGM, AOM_NotAllNSamp);
150   else if (DiffN)
151     UTwarn ("%s - %s", PGM, AOM_DiffNSamp);
152 
153   return Nframe;
154 }
155