~ubuntu-branches/ubuntu/raring/muse/raring-proposed

« back to all changes in this revision

Viewing changes to synti/stklib/AifWvIn.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Kobras
  • Date: 2004-02-07 15:18:22 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040207151822-es27xxkzbcxkebjm
Tags: 0.6.3-1
* New upstream version.
* Added patches:
  + [10_alsa_init_fix] New, from upstream CVS.
    Initialize direction variable when setting Alsa parameters.
  + [10_canvas_translation_fix] New, from upstream CVS.
    Do not translate tooltips twice in canvas popup.
  + [10_checkbox_fix] New, from upstream CVS.
    Use proper set/test methods on metronome checkboxes.
  + [10_html_doc_cleanup] New.
    Fix links and HTML errors in documentation.
  + [20_allow_system_timer] New.
    The new upstream version fails by default if the real-time clock
    could not be accessed (usually the case when not running suid-root).
    This patch reverts the old behaviour of falling back to the more
    inaccurate system timer.
* Updated patches:
  + [11_PIC_fixes_fixup] Rediffed.
* Removed patches:
  + [20_no_atomic_asm] Merged upstream.
* debian/compat: Splice out debhelper compatibility level from rules file.
* debian/control: Build-depend on latest jack release by default.
  Closes: #228788
* debian/control: Bump standards version.
* debian/control: Use auto-generated debconf dependency via misc:Depends.
* debian/control: Minor tweaks to the long description.
* debian/control: Tighten fluidsynth build dependency to sane version.
* debian/muse.doc-base: New. Register HTML documentation with doc-base.
* debian/templates: Tiny rewording, and typo fix.
* debian/templates, debian/po/*: Switch to po-debconf for translations.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*******************************************/
2
 
/*
3
 
  AifWvIn Input Class,
4
 
  by Gary P. Scavone, 2000
5
 
 
6
 
  This object inherits from WvIn and is
7
 
  used to open Audio Interchange File
8
 
  Format files with 16-bit data (signed
9
 
  integer) for playback.
10
 
 
11
 
  .aif files are always bif-endian.
12
 
*/
13
 
/*******************************************/
14
 
 
15
 
#include "AifWvIn.h"
16
 
 
17
 
#ifdef __LITTLE_ENDIAN__
18
 
  #include "ByteSwap.h"
19
 
#endif
20
 
 
21
 
AifWvIn :: AifWvIn(char *fileName, const char *mode)
22
 
{
23
 
  char msg[256];
24
 
 
25
 
  // check mode string
26
 
  if ( strcmp(mode,"oneshot") && strcmp(mode,"looping") ) {
27
 
    sprintf(msg, "AifWvIn: constructor parameter 'mode' must be oneshot or looping only.\n");
28
 
    throw StkError(msg, StkError::FUNCTION_SYNTAX);
29
 
  }
30
 
 
31
 
  // Open the file and get header info
32
 
  fd = fopen(fileName,"rb");
33
 
  if (!fd) {
34
 
    sprintf(msg, "AifWvIn: Couldn't open or find file (%s).\n", fileName);
35
 
    throw StkError(msg, StkError::FILE_NOT_FOUND);
36
 
  }
37
 
 
38
 
  // Make sure this is an .aif format file
39
 
  char id[4];
40
 
  fseek(fd,8,SEEK_SET); // Locate form type
41
 
  fread(&id,4,1,fd);
42
 
  if (strncmp(id,"AIFF",4)) {
43
 
    fclose(fd);
44
 
    sprintf(msg, "AifWvIn: %s doesn't appear to be an AIFF file.\n", fileName);
45
 
    throw StkError(msg, StkError::FILE_ERROR);
46
 
  }
47
 
 
48
 
  // Find "common" chunk
49
 
  INT32 chunkSize;
50
 
  fread(&id,4,1,fd);
51
 
  while (strncmp(id,"COMM",4)) {
52
 
    fread(&chunkSize,4,1,fd);
53
 
#ifdef __LITTLE_ENDIAN__
54
 
    swap32((unsigned char *)&chunkSize);
55
 
#endif
56
 
    fseek(fd,chunkSize,SEEK_CUR);
57
 
    fread(&id,4,1,fd);
58
 
  }
59
 
 
60
 
  // Get number of channels from the header
61
 
  INT16 temp;
62
 
  fseek(fd,4,SEEK_CUR); // Jump over chunk size
63
 
  fread(&temp,2,1,fd);
64
 
#ifdef __LITTLE_ENDIAN__
65
 
  swap16((unsigned char *)&temp);
66
 
#endif
67
 
  channels = temp;
68
 
 
69
 
  // Get length of data from the header
70
 
  INT32 frames;
71
 
  fread(&frames,4,1,fd);
72
 
#ifdef __LITTLE_ENDIAN__
73
 
  swap32((unsigned char *)&frames);
74
 
#endif
75
 
  // length is the number of sample frames
76
 
  fileSize = frames;
77
 
  bufferSize = fileSize;
78
 
 
79
 
  // Verify that the data is 16 bits per sample
80
 
  fread(&temp,2,1,fd);
81
 
#ifdef __LITTLE_ENDIAN__
82
 
  swap16((unsigned char *)&temp);
83
 
#endif
84
 
  if (temp != 16) {
85
 
    fclose(fd);
86
 
    sprintf(msg, "AifWvIn: STK does not currently support data formats other than 16 bit signed integer.\n");
87
 
    throw StkError(msg, StkError::FILE_ERROR);
88
 
  }
89
 
 
90
 
  /* Get file sample rate from the header and set the default rate.
91
 
   * For AIFF files, this value is stored in a 10-byte, IEEE Standard
92
 
   * 754 floating point number, so we need to convert it first.
93
 
   */
94
 
  unsigned char srate[10];
95
 
  unsigned char exp;
96
 
  unsigned long mantissa;
97
 
  unsigned long last = 0;;
98
 
  fread(&srate,10,1,fd);
99
 
  mantissa = (unsigned long) *(unsigned long *)(srate+2);
100
 
#ifdef __LITTLE_ENDIAN__
101
 
  swap32((unsigned char *)&mantissa);
102
 
#endif
103
 
  exp = 30 - *(srate+1);
104
 
  while (exp--) {
105
 
    last = mantissa;
106
 
    mantissa >>= 1;
107
 
  }
108
 
  if (last & 0x00000001) mantissa++;
109
 
  rate = (MY_FLOAT) (mantissa/SRATE);    // set default rate based on file sampling rate
110
 
 
111
 
  // Find "data" chunk
112
 
  fread(&id,4,1,fd);
113
 
  while (strncmp(id,"SSND",4)) {
114
 
    fread(&chunkSize,4,1,fd);
115
 
#ifdef __LITTLE_ENDIAN__
116
 
    swap32((unsigned char *)&chunkSize);
117
 
#endif
118
 
    fseek(fd,chunkSize,SEEK_CUR);
119
 
    fread(&id,4,1,fd);
120
 
  }
121
 
 
122
 
  // Skip over chunk size, offset, and blocksize fields
123
 
  fseek(fd,12,SEEK_CUR);
124
 
 
125
 
  if ((fileSize*channels) > MAX_FILE_LOAD_SIZE) {
126
 
    printf("\nAifWvIn: The .AIF file (%s) has more than %d samples and\n",
127
 
           fileName, MAX_FILE_LOAD_SIZE);
128
 
    printf("will be loaded incrementally from disk.  Normalization will be disabled.\n");
129
 
    chunking = 1;
130
 
    bufferSize = LOAD_BUFFER_SIZE;
131
 
  }
132
 
 
133
 
  // Setup for looping or one-shot playback
134
 
  if (!strcmp(mode,"looping"))
135
 
    looping = 1;
136
 
  else // default = oneshot
137
 
    looping = 0;
138
 
 
139
 
  data = (MY_FLOAT *) new MY_FLOAT[(bufferSize+1)*channels];
140
 
  dataOffset = ftell(fd);
141
 
  this->getData(0);    // Read samples into data[]
142
 
 
143
 
  if (fmod(rate, 1.0) != 0.0) interpolate = 1;
144
 
  else interpolate = 0;
145
 
  phaseOffset = (MY_FLOAT) 0.0;
146
 
  lastOutput = (MY_FLOAT *) new MY_FLOAT[channels];
147
 
  this->reset();
148
 
 
149
 
  // finally, let's normalize the data by default
150
 
  this->normalize();
151
 
}
152
 
 
153
 
AifWvIn :: ~AifWvIn()
154
 
{
155
 
}
156
 
 
157
 
void AifWvIn :: getData(long index)
158
 
{
159
 
  /* Compare index to current readPointer and modify as needed.
160
 
   * The following while() loops will only execute on calls subsequent
161
 
   * to class instantiation ... and thus, only when "chunking".
162
 
   */
163
 
  while (index < readPointer) {
164
 
    readPointer -= LOAD_BUFFER_SIZE;
165
 
    bufferSize = LOAD_BUFFER_SIZE;
166
 
    if (readPointer < 0) {
167
 
      bufferSize += readPointer;
168
 
      readPointer = 0;
169
 
    }
170
 
  }
171
 
  while (index >= readPointer+bufferSize) {
172
 
    readPointer += LOAD_BUFFER_SIZE;
173
 
    bufferSize = LOAD_BUFFER_SIZE;
174
 
    if (readPointer+LOAD_BUFFER_SIZE >= fileSize) {
175
 
      bufferSize = fileSize - readPointer;
176
 
    }
177
 
  }
178
 
 
179
 
  fseek(fd, dataOffset+(long)(readPointer*channels*2), SEEK_SET);
180
 
  long length = bufferSize;
181
 
  int end_of_file = (readPointer+bufferSize == fileSize);
182
 
  if (!end_of_file) length += 1;
183
 
 
184
 
  // Read samples into data[].  Use MY _FLOAT data structure to store INT16 samples
185
 
  INT16 *buf = (INT16 *)data;
186
 
  fread(buf, 2, length*channels, fd);
187
 
  // Convert in place (unpack) to MY_FLOAT from the end of the array
188
 
  for (int i=length*channels-1; i>=0; i--) {
189
 
#ifdef __LITTLE_ENDIAN__
190
 
    swap16((unsigned char *)(buf+i));
191
 
#endif
192
 
    data[i] = buf[i];
193
 
    if (chunking) data[i] *= 0.00003051;
194
 
  }
195
 
 
196
 
  // fill in the extra sample frame for interpolation
197
 
  if (end_of_file) {
198
 
    for (int j=0; j<channels; j++)
199
 
      if (looping)
200
 
        data[bufferSize*channels+j] = data[j];
201
 
      else
202
 
        data[bufferSize*channels+j] = data[(bufferSize-1)*channels+j];
203
 
  }
204
 
 
205
 
  if (!chunking) {
206
 
    fclose(fd);
207
 
    fd = 0;
208
 
  }
209
 
}