1
//=========================================================
4
// $Id: pcm.cpp,v 1.1 2002/01/30 12:08:39 muse Exp $
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
//=========================================================
18
//---------------------------------------------------------
20
// short to float, deinterleaving
21
//---------------------------------------------------------
23
static void les2f_array (short *buffer, unsigned frames, int channels,
24
float** pp, int index)
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;
34
//---------------------------------------------------------
36
// char to float, deinterleaving
37
//---------------------------------------------------------
39
static void les1f_array (char *buffer, unsigned frames, int channels,
40
float** pp, int index)
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;
50
//---------------------------------------------------------
52
// float to short, interleaving
53
//---------------------------------------------------------
55
static void f2les_array (float** ptr, int index, short *buffer,
56
unsigned frames, int channels)
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);
65
//---------------------------------------------------------
67
//---------------------------------------------------------
69
SndFileFormatWaveFloat::SndFileFormatWaveFloat(SndFile* s)
70
: SndFileFormatWave(s)
74
//---------------------------------------------------------
75
// SndFileFormatWavePCM1::read
76
//---------------------------------------------------------
78
size_t SndFileFormatWavePCM1::read(float** pp, unsigned len)
82
int channels = sfile->channels();
83
int framesize = sfile->blockwidth();
84
unsigned bufferlen = SF_BUFFER_LEN / framesize;
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);
90
if (frames < readcount) {
91
sfile->setErrno(SFE_SHORT_READ);
100
//---------------------------------------------------------
101
// SndFileFormatWavePCM2::read
103
//---------------------------------------------------------
105
size_t SndFileFormatWavePCM2::read(float** pp, unsigned len)
109
int channels = sfile->channels();
110
int framesize = sfile->blockwidth();
111
unsigned bufferlen = SF_BUFFER_LEN / framesize;
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);
117
if (frames < readcount) {
118
sfile->setErrno(SFE_SHORT_READ);
127
//---------------------------------------------------------
128
// SndFileFormatWavePCM2::write
130
//---------------------------------------------------------
132
size_t SndFileFormatWavePCM2::write(float**ptr, unsigned len)
136
int channels = sfile->channels();
137
int framesize = sfile->blockwidth();
138
unsigned bufferlen = SF_BUFFER_LEN / framesize;
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());
145
if (frames < writecount)
153
size_t SndFileFormatWavePCM3::read(float**, unsigned)
156
printf("not implemented: PCM3 read\n");
158
unsigned int readcount, thisread ;
159
int bytecount, bufferlen ;
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) ;
172
if (thisread < readcount)
174
index += thisread / sfile->bytewidth ;
175
bytecount -= thisread ;
178
total /= sfile->bytewidth ;
180
sfile->setErrno(SFE_SHORT_READ);
185
size_t SndFileFormatWavePCM4::read(float**, unsigned)
188
printf("not implemented: PCM4 read\n");
190
unsigned int readcount, thisread ;
191
int bytecount, bufferlen ;
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) ;
204
if (thisread < readcount)
206
index += thisread / sfile->bytewidth ;
207
bytecount -= thisread ;
210
total /= sfile->bytewidth ;
212
sfile->setErrno(SFE_SHORT_READ);
217
size_t SndFileFormatWaveFloat::read(float**, unsigned)
221
unsigned int readcount, thisread ;
222
int bytecount, bufferlen ;
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) ;
235
if (thisread < readcount)
237
index += thisread / sfile->bytewidth ;
238
bytecount -= thisread ;
241
total /= sfile->bytewidth ;
243
sfile->setErrno(SFE_SHORT_READ);
248
size_t SndFileFormatWavePCM1::write(float**, unsigned)
252
unsigned int writecount, thiswrite ;
253
int bytecount, bufferlen ;
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()) ;
266
if (thiswrite < writecount)
268
index += thiswrite / sfile->bytewidth ;
269
bytecount -= thiswrite ;
272
total /= sfile->bytewidth ;
274
sfile->setErrno(SFE_SHORT_WRITE);
279
size_t SndFileFormatWavePCM3::write(float**, unsigned)
283
unsigned int writecount, thiswrite ;
284
int bytecount, bufferlen ;
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()) ;
297
if (thiswrite < writecount)
299
index += thiswrite / sfile->bytewidth ;
300
bytecount -= thiswrite ;
303
total /= sfile->bytewidth ;
305
sfile->setErrno(SFE_SHORT_WRITE);
310
size_t SndFileFormatWavePCM4::write(float**, unsigned)
314
unsigned int writecount, thiswrite ;
315
int bytecount, bufferlen ;
319
normfact = (double) 0x80000000;
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()) ;
328
if (thiswrite < writecount)
330
index += thiswrite / sfile->bytewidth ;
331
bytecount -= thiswrite ;
334
total /= sfile->bytewidth ;
336
sfile->setErrno(SFE_SHORT_WRITE);
341
size_t SndFileFormatWaveFloat::write(float**, unsigned)
345
unsigned int writecount, thiswrite;
348
double normfact = 1.0;
349
int bufferlen = SF_BUFFER_LEN - (SF_BUFFER_LEN % sfile->blockwidth());
350
int bytecount = len * sfile->bytewidth;
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());
357
if (thiswrite < writecount)
359
index += thiswrite / sfile->bytewidth;
360
bytecount -= thiswrite;
363
total /= sfile->bytewidth;
365
sfile->setErrno(SFE_SHORT_WRITE);