File: get_audio.c

package info (click to toggle)
toolame 02i-2
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 604 kB
  • ctags: 558
  • sloc: ansic: 12,338; sh: 111; makefile: 96
file content (260 lines) | stat: -rw-r--r-- 6,476 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
#include <stdlib.h>
#include "common.h"
#include "encoder.h"
#include "options.h"


/************************************************************************
*
* read_samples()
*
* PURPOSE:  reads the PCM samples from a file to the buffer
*
*  SEMANTICS:
* Reads #samples_read# number of shorts from #musicin# filepointer
* into #sample_buffer[]#.  Returns the number of samples read.
*
************************************************************************/

unsigned long
read_samples (FILE * musicin,
	      short sample_buffer[2304],
	      unsigned long num_samples, unsigned long frame_size)
{
  unsigned long samples_read;
  static unsigned long samples_to_read;
  static char init = TRUE;

  if (init)
    {
      samples_to_read = num_samples;
      init = FALSE;
    }
  if (samples_to_read >= frame_size)
    samples_read = frame_size;
  else
    samples_read = samples_to_read;
  if ((samples_read =
       fread (sample_buffer, sizeof (short), (int) samples_read,
	      musicin)) == 0)
    fprintf (stderr, "Hit end of audio data\n");
  /*
     Samples are big-endian. If this is a little-endian machine
     we must swap
   */
  if (NativeByteOrder == order_unknown)
    {
      NativeByteOrder = DetermineByteOrder ();
      if (NativeByteOrder == order_unknown)
	{
	  fprintf (stderr, "byte order not determined\n");
	  exit (1);
	}
    }
  if (NativeByteOrder != order_littleEndian || (glopts.byteswap == TRUE))
    SwapBytesInWords (sample_buffer, samples_read);

  samples_to_read -= samples_read;
  if (samples_read < frame_size && samples_read > 0)
    {
      fprintf (stderr,
	       "Insufficient PCM input for one frame - fillout with zeros\n");
      for (; samples_read < frame_size; sample_buffer[samples_read++] = 0);
      samples_to_read = 0;
    }
  return (samples_read);
}

/************************************************************************
*
* get_audio()
*
* PURPOSE:  reads a frame of audio data from a file to the buffer,
*   aligns the data for future processing, and separates the
*   left and right channels
*
*
************************************************************************/
unsigned long
get_audio (FILE * musicin,
	   short FAR buffer[2][1152],
	   unsigned long num_samples, int stereo, layer * info)
{
  int j;
  short insamp[2304];
  unsigned long samples_read;

  if (stereo == 2)
    {				/* stereo */
      samples_read = read_samples (musicin, insamp, num_samples,
				   (unsigned long) 2304);
      if (glopts.channelswap == TRUE)
	{
	  for (j = 0; j < 1152; j++)
	    {
	      buffer[1][j] = insamp[2 * j];
	      buffer[0][j] = insamp[2 * j + 1];
	    }
	}
      else
	{
	  for (j = 0; j < 1152; j++)
	    {
	      buffer[0][j] = insamp[2 * j];
	      buffer[1][j] = insamp[2 * j + 1];
	    }
	}
    }
  else if (glopts.downmix == TRUE)
    {
      samples_read = read_samples (musicin, insamp, num_samples,
				   (unsigned long) 2304);
      for (j = 0; j < 1152; j++)
	{
	  buffer[0][j] = 0.5 * (insamp[2 * j] + insamp[2 * j + 1]);
	}
    }
  else
    {				/* mono */
      samples_read = read_samples (musicin, insamp, num_samples,
				   (unsigned long) 1152);
      for (j = 0; j < 1152; j++)
	{
	  buffer[0][j] = insamp[j];
	  /* buffer[1][j] = 0;  don't bother zeroing this buffer. MFC Nov 99 */
	}
    }
  return (samples_read);
}


/*****************************************************************************
*
*  Routines to determine byte order and swap bytes
*
*****************************************************************************/

enum byte_order
DetermineByteOrder (void)
{
  char s[sizeof (long) + 1];
  union
  {
    long longval;
    char charval[sizeof (long)];
  }
  probe;
  probe.longval = 0x41424344L;	/* ABCD in ASCII */
  strncpy (s, probe.charval, sizeof (long));
  s[sizeof (long)] = '\0';
  /* fprintf( stderr, "byte order is %s\n", s ); */
  if (strcmp (s, "ABCD") == 0)
    return order_bigEndian;
  else if (strcmp (s, "DCBA") == 0)
    return order_littleEndian;
  else
    return order_unknown;
}

void
SwapBytesInWords (short *loc, int words)
{
  int i;
  short thisval;
  char *dst, *src;
  src = (char *) &thisval;
  for (i = 0; i < words; i++)
    {
      thisval = *loc;
      dst = (char *) loc++;
      dst[0] = src[1];
      dst[1] = src[0];
    }
}

/*****************************************************************************
 *
 *  Read Audio Interchange File Format (AIFF) headers.
 *
 *****************************************************************************/

int
aiff_read_headers (FILE * file_ptr, IFF_AIFF * aiff_ptr)
{
  int chunkSize, subSize, sound_position;

  if (fseek (file_ptr, 0, SEEK_SET) != 0)
    return -1;

  if (Read32BitsHighLow (file_ptr) != IFF_ID_FORM)
    return -1;

  chunkSize = Read32BitsHighLow (file_ptr);

  if (Read32BitsHighLow (file_ptr) != IFF_ID_AIFF)
    return -1;

  sound_position = 0;
  while (chunkSize > 0)
    {
      chunkSize -= 4;
      switch (Read32BitsHighLow (file_ptr))
	{

	case IFF_ID_COMM:
	  chunkSize -= subSize = Read32BitsHighLow (file_ptr);
	  aiff_ptr->numChannels = Read16BitsHighLow (file_ptr);
	  subSize -= 2;
	  aiff_ptr->numSampleFrames = Read32BitsHighLow (file_ptr);
	  subSize -= 4;
	  aiff_ptr->sampleSize = Read16BitsHighLow (file_ptr);
	  subSize -= 2;
	  aiff_ptr->sampleRate = ReadIeeeExtendedHighLow (file_ptr);
	  subSize -= 10;
	  while (subSize > 0)
	    {
	      getc (file_ptr);
	      subSize -= 1;
	    }
	  break;

	case IFF_ID_SSND:
	  chunkSize -= subSize = Read32BitsHighLow (file_ptr);
	  aiff_ptr->blkAlgn.offset = Read32BitsHighLow (file_ptr);
	  subSize -= 4;
	  aiff_ptr->blkAlgn.blockSize = Read32BitsHighLow (file_ptr);
	  subSize -= 4;
	  sound_position = ftell (file_ptr) + aiff_ptr->blkAlgn.offset;
	  if (fseek (file_ptr, (long) subSize, SEEK_CUR) != 0)
	    return -1;
	  aiff_ptr->sampleType = IFF_ID_SSND;
	  break;

	default:
	  chunkSize -= subSize = Read32BitsHighLow (file_ptr);
	  while (subSize > 0)
	    {
	      getc (file_ptr);
	      subSize -= 1;
	    }
	  break;
	}
    }
  return sound_position;
}

/*****************************************************************************
 *
 *  Seek past some Audio Interchange File Format (AIFF) headers to sound data.
 *
 *****************************************************************************/

int
aiff_seek_to_sound_data (FILE * file_ptr)
{
  if (fseek
      (file_ptr, AIFF_FORM_HEADER_SIZE + AIFF_SSND_HEADER_SIZE,
       SEEK_SET) != 0)
    return (-1);
  return (0);
}