~ubuntu-branches/ubuntu/karmic/muse/karmic-proposed

« back to all changes in this revision

Viewing changes to sf/pcm.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Kobras
  • Date: 2002-04-23 17:28:23 UTC
  • Revision ID: james.westby@ubuntu.com-20020423172823-w8yplzr81a759xa3
Tags: upstream-0.5.2
ImportĀ upstreamĀ versionĀ 0.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//=========================================================
 
2
//  MusE
 
3
//  Linux Music Editor
 
4
//  $Id: pcm.cpp,v 1.1 2002/01/30 12:08:39 muse Exp $
 
5
//
 
6
//  (C) Copyright 2001 Werner Schweer (ws@seh.de)
 
7
//  based on libsndfile:
 
8
//  Copyright (C) 1999-2000 Erik de Castro Lopo <erikd@zip.com.au>
 
9
//=========================================================
 
10
 
 
11
#include <unistd.h>
 
12
#include <math.h>
 
13
#include "config.h"
 
14
#include "sndfile.h"
 
15
#include "sfendian.h"
 
16
#include "pcm.h"
 
17
 
 
18
//---------------------------------------------------------
 
19
//   les2f_array
 
20
//    short to float, deinterleaving
 
21
//---------------------------------------------------------
 
22
 
 
23
static void les2f_array (short *buffer, unsigned frames, int channels,
 
24
   float** pp, int index)
 
25
      {
 
26
      for (unsigned k = 0; k < frames*channels; k += channels) {
 
27
            for (int i = 0; i < channels; ++i) {
 
28
                  short value = buffer[k+i];
 
29
                      *(pp[i] + index + k/channels) = float(value) / 32767.0;
 
30
                  }
 
31
                }
 
32
      }
 
33
 
 
34
//---------------------------------------------------------
 
35
//   les1f_array
 
36
//    char to float, deinterleaving
 
37
//---------------------------------------------------------
 
38
 
 
39
static void les1f_array (char *buffer, unsigned frames, int channels,
 
40
   float** pp, int index)
 
41
      {
 
42
      for (unsigned k = 0; k < frames*channels; k += channels) {
 
43
            for (int i = 0; i < channels; ++i) {
 
44
                  char value = buffer[k+i];
 
45
                      *(pp[i] + index + k/channels) = float(value) / 128.0;
 
46
                  }
 
47
                }
 
48
      }
 
49
 
 
50
//---------------------------------------------------------
 
51
//   f2les_array
 
52
//    float to short, interleaving
 
53
//---------------------------------------------------------
 
54
 
 
55
static void f2les_array (float** ptr, int index, short *buffer,
 
56
   unsigned frames, int channels)
 
57
      {
 
58
        for (unsigned k = 0 ; k < frames; ++k) {
 
59
            for (int i = 0; i < channels; ++i) {
 
60
                  buffer[k*channels+i] = lrint(*(ptr[i] + index + k) * 32767.0);
 
61
                  }
 
62
            }
 
63
      }
 
64
 
 
65
//---------------------------------------------------------
 
66
//   SndFileFormatFloat
 
67
//---------------------------------------------------------
 
68
 
 
69
SndFileFormatWaveFloat::SndFileFormatWaveFloat(SndFile* s)
 
70
   : SndFileFormatWave(s)
 
71
      {
 
72
      }
 
73
 
 
74
//---------------------------------------------------------
 
75
//   SndFileFormatWavePCM1::read
 
76
//---------------------------------------------------------
 
77
 
 
78
size_t SndFileFormatWavePCM1::read(float** pp, unsigned len)
 
79
      { 
 
80
      unsigned total     = 0;
 
81
        int index          = 0;
 
82
      int channels       = sfile->channels();
 
83
        int framesize      = sfile->blockwidth();
 
84
        unsigned bufferlen = SF_BUFFER_LEN / framesize;
 
85
        while (len > 0) {       
 
86
            unsigned readcount = (len >= bufferlen) ? bufferlen : len;
 
87
                unsigned frames    = fread(buffer, framesize, readcount, sfile->file());
 
88
                les1f_array((char *) (buffer), frames, channels, pp, index);
 
89
                total += frames;
 
90
                if (frames < readcount) {
 
91
                      sfile->setErrno(SFE_SHORT_READ);
 
92
                        break;
 
93
                  }
 
94
                index += frames;
 
95
                len   -= frames;
 
96
                }
 
97
        return total;
 
98
      }
 
99
 
 
100
//---------------------------------------------------------
 
101
//   SndFileFormatWavePCM2::read
 
102
//    read len frames
 
103
//---------------------------------------------------------
 
104
 
 
105
size_t SndFileFormatWavePCM2::read(float** pp, unsigned len)
 
106
      { 
 
107
      unsigned total     = 0;
 
108
        int index          = 0;
 
109
      int channels       = sfile->channels();
 
110
        int framesize      = sfile->blockwidth();
 
111
        unsigned bufferlen = SF_BUFFER_LEN / framesize;
 
112
        while (len > 0) {       
 
113
            unsigned readcount = (len >= bufferlen) ? bufferlen : len;
 
114
                unsigned frames    = fread(buffer, framesize, readcount, sfile->file());
 
115
                les2f_array((short*) (buffer), frames, channels, pp, index);
 
116
                total += frames;
 
117
                if (frames < readcount) {
 
118
                      sfile->setErrno(SFE_SHORT_READ);
 
119
                        break;
 
120
                  }
 
121
                index += frames;
 
122
                len   -= frames;
 
123
                }
 
124
        return total;
 
125
      }
 
126
 
 
127
//---------------------------------------------------------
 
128
//   SndFileFormatWavePCM2::write
 
129
//    write len frames
 
130
//---------------------------------------------------------
 
131
 
 
132
size_t SndFileFormatWavePCM2::write(float**ptr, unsigned len)
 
133
      { 
 
134
      unsigned total        = 0;
 
135
        int index             = 0;
 
136
      int channels          = sfile->channels();
 
137
        int framesize         = sfile->blockwidth();
 
138
        unsigned bufferlen    = SF_BUFFER_LEN / framesize;
 
139
        
 
140
        while (len > 0) {       
 
141
            unsigned writecount = (len >= bufferlen) ? bufferlen : len;
 
142
                f2les_array (ptr, index, (short*) buffer, writecount, channels);
 
143
                unsigned frames = fwrite (buffer, framesize, writecount, sfile->file());
 
144
                total += frames;
 
145
                if (frames < writecount)
 
146
                        break;
 
147
                index  += frames;
 
148
                len    -= frames;
 
149
                }
 
150
        return total;
 
151
      }
 
152
 
 
153
size_t SndFileFormatWavePCM3::read(float**, unsigned)
 
154
      { 
 
155
      unsigned total = 0;
 
156
      printf("not implemented: PCM3 read\n");
 
157
#if 0
 
158
      unsigned int readcount, thisread ;
 
159
        int             bytecount, bufferlen ;
 
160
        int             index = 0;
 
161
        double          normfact ;
 
162
 
 
163
        normfact = 1.0;
 
164
 
 
165
        bufferlen = SF_BUFFER_LEN - (SF_BUFFER_LEN % sfile->blockwidth()) ;
 
166
        bytecount = len * sfile->bytewidth ;
 
167
        while (bytecount > 0)
 
168
        {       readcount = (bytecount >= bufferlen) ? bufferlen : bytecount ;
 
169
                thisread = fread (sfile->buffer, 1, readcount, sfile->file()) ;
 
170
                let2f_array ((tribyte*) (sfile->buffer), thisread / sfile->bytewidth, ptr, index, normfact) ;
 
171
                total += thisread ;
 
172
                if (thisread < readcount)
 
173
                        break ;
 
174
                index += thisread / sfile->bytewidth ;
 
175
                bytecount -= thisread ;
 
176
                } ;
 
177
 
 
178
        total /= sfile->bytewidth ;
 
179
        if (total < len)
 
180
                sfile->setErrno(SFE_SHORT_READ);
 
181
#endif
 
182
        return total;
 
183
      }
 
184
 
 
185
size_t SndFileFormatWavePCM4::read(float**, unsigned)
 
186
      { 
 
187
      unsigned total = 0;
 
188
      printf("not implemented: PCM4 read\n");
 
189
#if 0
 
190
      unsigned int readcount, thisread ;
 
191
        int             bytecount, bufferlen ;
 
192
        int             index = 0;
 
193
        double          normfact ;
 
194
 
 
195
        normfact = 1.0;
 
196
 
 
197
        bufferlen = SF_BUFFER_LEN - (SF_BUFFER_LEN % sfile->blockwidth()) ;
 
198
        bytecount = len * sfile->bytewidth ;
 
199
        while (bytecount > 0)
 
200
        {       readcount = (bytecount >= bufferlen) ? bufferlen : bytecount ;
 
201
                thisread = fread (sfile->buffer, 1, readcount, sfile->file()) ;
 
202
                lei2f_array ((int*) (sfile->buffer), thisread / sfile->bytewidth, ptr, index, normfact) ;
 
203
                total += thisread ;
 
204
                if (thisread < readcount)
 
205
                        break ;
 
206
                index += thisread / sfile->bytewidth ;
 
207
                bytecount -= thisread ;
 
208
                } ;
 
209
 
 
210
        total /= sfile->bytewidth ;
 
211
        if (total < len)
 
212
                sfile->setErrno(SFE_SHORT_READ);
 
213
#endif
 
214
        return total;
 
215
      }
 
216
 
 
217
size_t SndFileFormatWaveFloat::read(float**, unsigned)
 
218
      { 
 
219
      unsigned total = 0;
 
220
#if 0
 
221
      unsigned int readcount, thisread ;
 
222
        int             bytecount, bufferlen ;
 
223
        int     index = 0;
 
224
        double normfact;
 
225
 
 
226
        normfact = 1.0;
 
227
 
 
228
        bufferlen = SF_BUFFER_LEN - (SF_BUFFER_LEN % sfile->blockwidth()) ;
 
229
        bytecount = len * sfile->bytewidth ;
 
230
        while (bytecount > 0)
 
231
        {       readcount = (bytecount >= bufferlen) ? bufferlen : bytecount ;
 
232
                thisread = fread (sfile->buffer, 1, readcount, sfile->file()) ;
 
233
                f2f_array ((float*) (sfile->buffer), thisread / sfile->bytewidth, ptr, index, normfact) ;
 
234
                total += thisread ;
 
235
                if (thisread < readcount)
 
236
                        break ;
 
237
                index += thisread / sfile->bytewidth ;
 
238
                bytecount -= thisread ;
 
239
                } ;
 
240
 
 
241
        total /= sfile->bytewidth ;
 
242
        if (total < len)
 
243
                sfile->setErrno(SFE_SHORT_READ);
 
244
#endif
 
245
        return total;
 
246
      }
 
247
 
 
248
size_t SndFileFormatWavePCM1::write(float**, unsigned)
 
249
      { 
 
250
      unsigned total = 0;
 
251
#if  0
 
252
      unsigned int      writecount, thiswrite ;
 
253
        int     bytecount, bufferlen ;
 
254
        int             index = 0;
 
255
        double          normfact ;
 
256
        
 
257
        normfact = 1.0;
 
258
 
 
259
        bufferlen = SF_BUFFER_LEN - (SF_BUFFER_LEN % sfile->blockwidth()) ;
 
260
        bytecount = len * sfile->bytewidth ;
 
261
        while (bytecount > 0)
 
262
        {       writecount = (bytecount >= bufferlen) ? bufferlen : bytecount ;
 
263
                f2uc_array (ptr, index, (unsigned char*) (sfile->buffer), writecount / sfile->bytewidth, normfact) ;
 
264
                thiswrite = fwrite (sfile->buffer, 1, writecount, sfile->file()) ;
 
265
                total += thiswrite ;
 
266
                if (thiswrite < writecount)
 
267
                        break ;
 
268
                index += thiswrite / sfile->bytewidth ;
 
269
                bytecount -= thiswrite ;
 
270
                } ;
 
271
 
 
272
        total /= sfile->bytewidth ;
 
273
        if (total < len)
 
274
                sfile->setErrno(SFE_SHORT_WRITE);
 
275
#endif
 
276
        return total;
 
277
      }
 
278
 
 
279
size_t SndFileFormatWavePCM3::write(float**, unsigned)
 
280
      { 
 
281
      unsigned total = 0;
 
282
#if 0
 
283
      unsigned int      writecount, thiswrite ;
 
284
        int     bytecount, bufferlen ;
 
285
        int             index = 0;
 
286
        double          normfact ;
 
287
        
 
288
        normfact = 1.0;
 
289
 
 
290
        bufferlen = SF_BUFFER_LEN - (SF_BUFFER_LEN % sfile->blockwidth()) ;
 
291
        bytecount = len * sfile->bytewidth ;
 
292
        while (bytecount > 0)
 
293
        {       writecount = (bytecount >= bufferlen) ? bufferlen : bytecount ;
 
294
                f2let_array (ptr, index, (tribyte*) (sfile->buffer), writecount / sfile->bytewidth, normfact) ;
 
295
                thiswrite = fwrite (sfile->buffer, 1, writecount, sfile->file()) ;
 
296
                total += thiswrite ;
 
297
                if (thiswrite < writecount)
 
298
                        break ;
 
299
                index += thiswrite / sfile->bytewidth ;
 
300
                bytecount -= thiswrite ;
 
301
                } ;
 
302
 
 
303
        total /= sfile->bytewidth ;
 
304
        if (total < len)
 
305
                sfile->setErrno(SFE_SHORT_WRITE);
 
306
#endif
 
307
        return total;
 
308
      }
 
309
 
 
310
size_t SndFileFormatWavePCM4::write(float**, unsigned)
 
311
      { 
 
312
      unsigned total = 0;
 
313
#if 0
 
314
      unsigned int      writecount, thiswrite ;
 
315
        int     bytecount, bufferlen ;
 
316
        int             index = 0;
 
317
        double          normfact ;
 
318
        
 
319
        normfact = (double) 0x80000000;
 
320
 
 
321
        bufferlen = SF_BUFFER_LEN - (SF_BUFFER_LEN % sfile->blockwidth()) ;
 
322
        bytecount = len * sfile->bytewidth ;
 
323
        while (bytecount > 0)
 
324
        {       writecount = (bytecount >= bufferlen) ? bufferlen : bytecount ;
 
325
                f2lei_array (ptr, index, (int*) (sfile->buffer), writecount / sfile->bytewidth, normfact) ;
 
326
                thiswrite = fwrite (sfile->buffer, 1, writecount, sfile->file()) ;
 
327
                total += thiswrite ;
 
328
                if (thiswrite < writecount)
 
329
                        break ;
 
330
                index += thiswrite / sfile->bytewidth ;
 
331
                bytecount -= thiswrite ;
 
332
                } ;
 
333
 
 
334
        total /= sfile->bytewidth ;
 
335
        if (total < len)
 
336
                sfile->setErrno(SFE_SHORT_WRITE);
 
337
#endif
 
338
        return total;
 
339
      }
 
340
 
 
341
size_t SndFileFormatWaveFloat::write(float**, unsigned)
 
342
      { 
 
343
      unsigned total = 0;
 
344
#if 0
 
345
      unsigned int writecount, thiswrite;
 
346
        int index = 0;
 
347
 
 
348
        double normfact = 1.0;
 
349
        int bufferlen = SF_BUFFER_LEN - (SF_BUFFER_LEN % sfile->blockwidth());
 
350
        int bytecount = len * sfile->bytewidth;
 
351
 
 
352
        while (bytecount > 0) { 
 
353
            writecount = (bytecount >= bufferlen) ? bufferlen : bytecount;
 
354
                f2f_array (ptr, index, (float*) (sfile->buffer), writecount / sfile->bytewidth, normfact);
 
355
                thiswrite = fwrite (sfile->buffer, 1, writecount, sfile->file());
 
356
                total += thiswrite;
 
357
                if (thiswrite < writecount)
 
358
                        break;
 
359
                index += thiswrite / sfile->bytewidth;
 
360
                bytecount -= thiswrite;
 
361
                } ;
 
362
 
 
363
        total /= sfile->bytewidth;
 
364
        if (total < len)
 
365
                sfile->setErrno(SFE_SHORT_WRITE);
 
366
#endif
 
367
        return total;
 
368
      }
 
369