~ubuntu-branches/ubuntu/breezy/muse/breezy

« back to all changes in this revision

Viewing changes to synti/stklib/MatWvIn.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
 
/*  MatWvIn Input Class,                   */
3
 
/*  by Gary P. Scavone, 1999               */
4
 
/*                                         */
5
 
/*  This object inherits from WvIn and is  */
6
 
/*  used to open Matlab MAT-file data      */
7
 
/*  (doubles) files for playback.  In      */
8
 
/*  order for this class to work, the      */
9
 
/*  MAT-file must contain a single array   */
10
 
/*  (matrix) of double-precision floating  */
11
 
/*  point values (can be multi-channel).   */
12
 
/*  It does not work for any other data    */
13
 
/*  formats.                               */
14
 
/*                                         */
15
 
/*  MAT-file data is either big- or        */
16
 
/*  little-endian, which can be determined */
17
 
/*  from the header.                       */
18
 
/*******************************************/
19
 
 
20
 
#include "MatWvIn.h"
21
 
#include "ByteSwap.h"
22
 
 
23
 
MatWvIn :: MatWvIn(char *fileName, char *mode)
24
 
{
25
 
  char msg[256];
26
 
 
27
 
  // check mode string
28
 
  if ( strcmp(mode,"oneshot") && strcmp(mode,"looping") ) {
29
 
    sprintf(msg, "MatWvIn: constructor parameter 'mode' must be oneshot or looping only.\n");
30
 
    throw StkError(msg, StkError::FUNCTION_SYNTAX);
31
 
  }
32
 
 
33
 
  // Open the file and get header info
34
 
  fd = fopen(fileName,"rb");
35
 
  if (!fd)   {
36
 
    sprintf(msg, "MatWvIn: Couldn't open or find MAT-file (%s).\n", fileName);
37
 
    throw StkError(msg, StkError::FILE_NOT_FOUND);
38
 
  }
39
 
 
40
 
  // Make sure this is a version 5 MAT-file format and find its endian-ness
41
 
  char head[4];
42
 
  fseek(fd,0,SEEK_SET);
43
 
  fread(&head,4,1,fd);   // If any of the first 4 characters of the header = 0,
44
 
  if (strstr(head,"0")) { // then this is a Version 4 MAT-file.
45
 
    fclose(fd);
46
 
    sprintf(msg, "MatWvIn: %s appears to be a Version 4 \nMAT-file, which is not currently supported.\n",
47
 
            fileName);
48
 
    throw StkError(msg, StkError::FILE_ERROR);
49
 
  }
50
 
  char mi[2];
51
 
  doSwap = 0;
52
 
  fseek(fd,126,SEEK_SET);   // Locate "M" and "I" characters in header
53
 
  fread(&mi,2,1,fd);
54
 
#ifdef __LITTLE_ENDIAN__
55
 
  if (!strncmp(mi,"MI",2)) {
56
 
    doSwap = 1;
57
 
  } else if (strncmp(mi,"IM",2)) {
58
 
    fclose(fd);
59
 
    sprintf(msg, "MatWvIn: %s doesn't appear to be a MAT-file.\n", fileName);
60
 
    throw StkError(msg, StkError::FILE_ERROR);
61
 
  }
62
 
#else
63
 
  if (!strncmp(mi,"IM",2)) {
64
 
    doSwap = 1;
65
 
  } else if (strncmp(mi,"MI",2)) {
66
 
    fclose(fd);
67
 
    sprintf(msg, "MatWvIn: %s doesn't appear to be a MAT-file.\n", fileName);
68
 
    throw StkError(msg, StkError::FILE_ERROR);
69
 
  }
70
 
#endif
71
 
 
72
 
  // Check the data element type
73
 
  INT32 datatype;
74
 
  fread(&datatype,4,1,fd);
75
 
  if (doSwap) swap32((unsigned char *)&datatype);
76
 
  if (datatype != 14) {
77
 
    fclose(fd);
78
 
    sprintf(msg, "MatWvIn: I'm expecting a single array (or matrix) data element.\n");
79
 
    throw StkError(msg, StkError::FILE_ERROR);
80
 
  }
81
 
 
82
 
  // Check the array data type
83
 
  INT32 tmp;
84
 
  INT32 size;
85
 
  fseek(fd,168,SEEK_SET);
86
 
  fread(&tmp,4,1,fd);
87
 
  if (doSwap) swap32((unsigned char *)&tmp);
88
 
  if (tmp == 1) {  // array name > 4 characters
89
 
    fread(&tmp,4,1,fd);  // get array name length
90
 
    if (doSwap) swap32((unsigned char *)&tmp);
91
 
    size = (INT32) ceil((float)tmp/8);
92
 
    fseek(fd,size*8,SEEK_CUR);  // jump over array name
93
 
  }
94
 
  else { // array name <= 4 characters, compressed data element
95
 
    fseek(fd,4,SEEK_CUR);
96
 
  }
97
 
  fread(&tmp,4,1,fd);
98
 
  if (doSwap) swap32((unsigned char *)&tmp);
99
 
  if (tmp != 9) {
100
 
    fclose(fd);
101
 
    sprintf(msg, "MatWvIn: I'm expecting the array data to be in double precision floating-point format.\n");
102
 
    throw StkError(msg, StkError::FILE_ERROR);
103
 
  }
104
 
 
105
 
  // Get number of rows from the header
106
 
  INT32 rows;
107
 
  fseek(fd,160,SEEK_SET);
108
 
  fread(&rows,4,1,fd);
109
 
  if (doSwap) swap32((unsigned char *)&rows);
110
 
 
111
 
  // Get number of columns from the header
112
 
  INT32 columns;
113
 
  fread(&columns,4,1,fd); // columns
114
 
  if (doSwap) swap32((unsigned char *)&columns);
115
 
 
116
 
  // Make channels = smaller of rows or columns
117
 
  if (rows < columns) {
118
 
    channels = rows;
119
 
    fileSize = columns;
120
 
    interleaved = 1;
121
 
  }
122
 
  else {
123
 
    channels = columns;
124
 
    fileSize = rows;
125
 
    interleaved = 0;
126
 
  }
127
 
  bufferSize = fileSize;
128
 
 
129
 
  if ((fileSize*channels) > MAX_FILE_LOAD_SIZE) {
130
 
    printf("\nMatWvIn: The MAT-file (%s) has more than %d samples and\n",
131
 
           fileName, MAX_FILE_LOAD_SIZE);
132
 
    printf("will be loaded incrementally from disk.  Normalization will be disabled.\n");
133
 
    chunking = 1;
134
 
    bufferSize = LOAD_BUFFER_SIZE;
135
 
  }
136
 
 
137
 
  // Setup for looping or one-shot playback
138
 
  if (!strcmp(mode,"looping"))
139
 
    looping = 1;
140
 
  else // default = oneshot
141
 
    looping = 0;
142
 
 
143
 
  data = (MY_FLOAT *) new MY_FLOAT[(bufferSize+1)*channels];
144
 
 
145
 
  // Move read pointer to the data in the file
146
 
  INT32 headsize;
147
 
  fseek(fd,132,SEEK_SET);
148
 
  fread(&headsize,4,1,fd); // file size from 132nd byte
149
 
  if (doSwap) swap32((unsigned char *)&headsize);
150
 
  headsize -= fileSize * 8 * channels;
151
 
  fseek(fd,headsize,SEEK_CUR);
152
 
  dataOffset = ftell(fd);
153
 
 
154
 
  this->getData(0);    // Read samples into data[]
155
 
 
156
 
  rate = (MY_FLOAT) 1.0;
157
 
  interpolate = 0;
158
 
  phaseOffset = (MY_FLOAT) 0.0;
159
 
  lastOutput = (MY_FLOAT *) new MY_FLOAT[channels];
160
 
  this->reset();
161
 
}
162
 
 
163
 
MatWvIn :: ~MatWvIn()
164
 
{
165
 
}
166
 
 
167
 
void MatWvIn :: getData(long index)
168
 
{
169
 
  /* Compare index to current readPointer and modify as needed.
170
 
   * The following while() loops will only execute on calls subsequent
171
 
   * to class instantiation ... and thus, only when "chunking".
172
 
   */
173
 
  while (index < readPointer) {
174
 
    readPointer -= LOAD_BUFFER_SIZE;
175
 
    bufferSize = LOAD_BUFFER_SIZE;
176
 
    if (readPointer < 0) {
177
 
      bufferSize += readPointer;
178
 
      readPointer = 0;
179
 
    }
180
 
  }
181
 
  while (index >= readPointer+bufferSize) {
182
 
    readPointer += LOAD_BUFFER_SIZE;
183
 
    bufferSize = LOAD_BUFFER_SIZE;
184
 
    if (readPointer+LOAD_BUFFER_SIZE >= fileSize) {
185
 
      bufferSize = fileSize - readPointer;
186
 
    }
187
 
  }
188
 
 
189
 
  long length = bufferSize;
190
 
  int end_of_file = (readPointer+bufferSize == fileSize);
191
 
  if (!end_of_file) length += 1;
192
 
 
193
 
  // Read samples into data[].  Use MY _FLOAT data structure to store doubles
194
 
  double *buf = (double *)data;
195
 
  if (interleaved) {
196
 
    fseek(fd, dataOffset+(long)(readPointer*channels*8), SEEK_SET);
197
 
    fread(data, 8, length*channels, fd);
198
 
    for (int i=length*channels-1; i>=0; i--) {
199
 
      if (doSwap)
200
 
        swap64((unsigned char *)(buf+i));
201
 
      data[i] = buf[i];
202
 
    }
203
 
  }
204
 
  else {
205
 
    long i = 0;
206
 
    long j = 0;
207
 
    double temp;
208
 
    fseek(fd, dataOffset+(long)(readPointer*8), SEEK_SET);
209
 
    while (j < channels) {
210
 
      fread(&temp,8,1,fd);
211
 
      if (doSwap) swap64((unsigned char *)&temp);
212
 
      data[channels*i+j] = (MY_FLOAT) temp;
213
 
      i++;
214
 
      if (i>=length) {
215
 
        i = 0;
216
 
        j++;
217
 
        fseek(fd, dataOffset+(long)(((j*fileSize)+readPointer)*8), SEEK_SET);
218
 
      }
219
 
    }
220
 
  }
221
 
 
222
 
  // fill in the extra sample frame for interpolation
223
 
  if (end_of_file) {
224
 
    for (int j=0; j<channels; j++)
225
 
      if (looping)
226
 
        data[bufferSize*channels+j] = data[j];
227
 
      else
228
 
        data[bufferSize*channels+j] = data[(bufferSize-1)*channels+j];
229
 
  }
230
 
 
231
 
  if (!chunking) {
232
 
    fclose(fd);
233
 
    fd = 0;
234
 
  }
235
 
}