CSL  6.0
SoundFile.cpp
Go to the documentation of this file.
1 //
2 // Abst_SoundFile.cpp -- CSL's abstract sound file class
3 // See the copyright notice and acknowledgment of authors in the file COPYRIGHT
4 //
5 
6 #include "SoundFile.h"
7 
8 #ifdef USE_TAGS
9 #include <taglib/fileref.h> // libTag includes
10 #include <taglib/tag.h>
11 #endif
12 
13 using namespace csl;
14 
16 
18  if (mTitle.empty()) {
19  logMsg("No metadata");
20  return;
21  }
22  int secs = mLength % 60; // make a mins:secs display for the duration
23  int mins = (mLength - secs) / 60;
24  char dur[CSL_WORD_LEN];
25  if (secs < 10)
26  sprintf(dur, "%d:0%d", mins, secs);
27  else
28  sprintf(dur, "%d:%d", mins, secs);
29  logMsg("Tags: \"%s\" - %s - %s - %d - %s min",
30  mTitle.c_str(), mArtist.c_str(), mAlbum.c_str(), mYear, dur);
31  logMsg(" trk %d - %s - %d kbps - %d Hz - %d ch",
33 // if ( ! mComment.empty())
34 // logMsg(" Comment: %s", mComment.c_str());
35 }
36 
37 
38 /// Sound file name extensions we recognize - ToDo: should this be in a config file?
39 
40 const char * gSndFileExts[] = { "mp3", "wav", "aiff", "aif", "mp4", "m4p", "m4b", "m4a", "aac", "flac", 0 };
41 
42 ///< Answer whether the given name looks like a snd file
43 
44 bool Abst_SoundFile::isSndfileName(const char * path) {
45  const char * dot = strrchr(path, '.'); // find file name ext
46  if ( ! dot)
47  return false;
48  dot++;
49  if ( ! dot)
50  return false;
51  for (unsigned i = 0; gSndFileExts[i]; i++) {
52  if(strcasestr(dot, gSndFileExts[i]))
53  return true;
54  }
55  return false;
56 }
57 
58 ///< Answer the snd file type
59 
61  const char * lastDot = strrchr(path, '.'); // find the last dot in the name
62  if ( ! lastDot)
63  return kSoundFileFormatOther;
64  lastDot++;
65  if ( ! lastDot)
66  return kSoundFileFormatOther;
67  if (strcasestr(lastDot, "wav")) // guess the file type from the file name
68  return kSoundFileFormatWAV;
69  if (strcasestr(lastDot, "mp3"))
70  return kSoundFileFormatMP3;
71  if (strcasestr(lastDot, "aif"))
72  return kSoundFileFormatAIFF;
73  if (strcasestr(lastDot, "aiff"))
74  return kSoundFileFormatAIFF;
75  if (strcasestr(lastDot, "m4a"))
76  return kSoundFileFormatMP4;
77  if (strcasestr(lastDot, "mp4"))
78  return kSoundFileFormatMP4;
79  if (strcasestr(lastDot, "m4b"))
80  return kSoundFileFormatMP4;
81  if (strcasestr(lastDot, "aac"))
82  return kSoundFileFormatAAC;
83  if (strcasestr(lastDot, "flac"))
84  return kSoundFileFormatFLAC;
85  if (strcasestr(lastDot, "caf"))
86  return kSoundFileFormatCAF;
87  if (strcasestr(lastDot, "ogg"))
88  return kSoundFileFormatOGG;
89  if (strcasestr(lastDot, "shn"))
90  return kSoundFileFormatSHN;
91  if (strcasestr(lastDot, "snd"))
92  return kSoundFileFormatSND;
93  return kSoundFileFormatOther;
94 }
95 
96 // Answer the MIME type based on the file name
97 
98 const char * Abst_SoundFile::mimeType(const char * path) {
100  switch (fmt) {
101  case kSoundFileFormatAIFF: return "audio/x-aiff";
102  case kSoundFileFormatMP3: return "audio/mpeg";
103  case kSoundFileFormatMP4: return "audio/mp4a-latm";
104  case kSoundFileFormatWAV: return "audio/x-wav";
105  default: return "audio/basic";
106  }
107 }
108 
109 // Abst_SoundFile Constructors
110 
111 Abst_SoundFile::Abst_SoundFile(string tpath, int tstart, int tstop) :
113  mProperties(0),
114  mPath(string(tpath)),
115  mMode(kSoundFileClosed),
116  mFormat(kSoundFileFormatOther),
117  mIsValid(false),
118  mIsLooping(false),
119  mStart(tstart),
120  mStop(tstop),
121  mRate(1.0),
122  mNumFrames(0),
123  mBytesPerSample(0),
124  mBase(0) { /* no-op */}
125 
126 ///< Copy constructor -- shares sample buffer
127 
130  mProperties(otherSndFile.mProperties),
131  mMode(otherSndFile.mode()),
132  mIsValid(otherSndFile.isValid()),
133  mIsLooping(otherSndFile.isLooping()),
134  mStart(otherSndFile.startFrame()),
135  mStop(otherSndFile.stopFrame()),
136  mRate(otherSndFile.playbackRate()),
137  mBase(otherSndFile.mBase) {
138  this->setWaveform(otherSndFile.mWavetable);
139  mCurrentFrame = 0;
140  if ( ! otherSndFile.isCached())
141  logMsg(kLogError, "Cannot copy uncached sound file \"%s\"", mPath.c_str());
142  setPath(otherSndFile.path());
143 }
144 
145 // Clean up data allocated
146 
148 // freeBuffer(); this is done by the WaveTableOsc destructor
149  if (mProperties)
150  delete mProperties;
151 }
152 
153 void Abst_SoundFile::setPath(string tpath) {
154  mPath = tpath;
155 }
156 
157 unsigned Abst_SoundFile::channels() const {
158  return mIsValid ? mNumChannels : 0;
159 }
160 
162  return mIsValid ? ((float) (mStop - mStart) / (float) mFrameRate) : 0.0;
163 }
164 
166  if (mWavetable.mAreBuffersAllocated) // if no buffer allocated
168 }
169 
170 // check if the buffer's big enough
171 
172 void Abst_SoundFile::checkBuffer(unsigned numFrames) {
173  if ( ! mWavetable.mAreBuffersAllocated) { // if no sample read buffer allocated
175  mWavetable.setSize(mNumChannels, numFrames);
177  } else if (mWavetable.mNumFrames < numFrames) { // if asking for more samples than fit in the buffer
178  logMsg("Reallocating sound file buffers (%d)", numFrames * mNumChannels);
180  mWavetable.setSize(mNumChannels, numFrames);
182  }
183 //#ifdef CSL_USE_SRConv
184 // if ( ! mSRConvBuffer.mAreBuffersAllocated) { // if no SRC buffer allocated
185 // mSRConvBuffer.setSize(1, CGestalt::maxBufferFrames() * mNumChannels);
186 // mSRConvBuffer.allocateBuffers();
187 // }
188 //#endif
189 }
190 
191 void Abst_SoundFile::checkBuffer(unsigned numChans, unsigned numFrames) {
192  if ( ! mWavetable.mAreBuffersAllocated) { // if no sample read buffer allocated
193  mNumChannels = numChans;
194  mWavetable.setSize(mNumChannels, numFrames);
196  // if asking for more samples than fit in the buffer
197  } else if ((mWavetable.mNumFrames < numFrames) || (mNumChannels != numChans)) {
198  logMsg("Reallocating sound file buffers (%d)", numFrames * mNumChannels);
199  mNumChannels = numChans;
201  mWavetable.setSize(mNumChannels, numFrames);
203  }
204 }
205 
206 // average all the channels to mono
207 
210  logMsg("Abst_SoundFile::mergeToMono - buffers not allocated");
211  return;
212  }
213  if (mNumChannels == 1) {
214  logMsg("Abst_SoundFile::mergeToMono - sound file already mono");
215  return;
216  }
217  Buffer newBuf(1, mWavetable.mNumFrames); // create a new mono buffer
218  newBuf.allocateBuffers();
219  // sum channels
220  unsigned numCh = mNumChannels;
221  for (unsigned i = 0; i < mWavetable.mNumFrames; i++) {
222  sample sum = 0.0f;
223  for (unsigned j = 0; j < numCh; j++)
224  sum += (mWavetable.buffer(j))[i];
225  // store the average
226  newBuf.setBuffer(0, i, sum / numCh);
227  } // now overwrite my own mWavetable
228  mWavetable.copyFrom(newBuf);
229  newBuf.mDidIAllocateBuffers = false;
231  mNumChannels = 1;
232 }
233 
234 // Abst_SoundFile::convertRate - perform sample-rate conversion
235 
236 void Abst_SoundFile::convertRate(int fromRate, int toRate) {
237 #ifndef USE_SRC
238  return;
239 #else
240  mWavetable.convertRate(fromRate, toRate);
241  mFrameRate = toRate;
243 #endif
244 }
245 
246 // ~~~~~~~ Accessors ~~~~~~~~
247 
248 void Abst_SoundFile::setStart(int val) {
249  mStart = val;
250  if (mStart < 0)
251  mStart = 0;
252  if ((unsigned) mStart >= duration())
253  mStart = (int) duration();
254  if (mIsValid)
255  seekTo(mStart);
256 }
257 
259  setStart((int) (val * mFrameRate));
260 }
261 
263  setStart((int) (val * duration()));
264 }
265 
266 void Abst_SoundFile::setStop(int val) {
267  mStop = val;
268  if (mStop < 0)
269  mStop = 0;
270  int du = (int) duration();
271  if (mStop > du)
272  mStop = du;
273 }
274 
275 void Abst_SoundFile::setStopSec(float val) {
276  setStop((int) (val * mFrameRate));
277 }
278 
280  setStop((int) (val * duration()));
281 }
282 
283 void Abst_SoundFile::setBase(int val) {
284  mBase = val;
285 }
286 
287 // Rate and transposition
288 
290  if ( ! mInputs[CSL_RATE])
291  this->addInput(CSL_RATE, frequency);
292  else
293  mInputs[CSL_RATE]->mUGen = & frequency;
294 }
295 
296 void Abst_SoundFile::setRate(float frequency) {
297  mRate = frequency;
298 #ifdef CSL_DEBUG
299  logMsg("FrequencyAmount::set scale input value");
300 #endif
301 }
302 
304  if ( ! mIsValid)
305  return false;
306  return (mCurrentFrame < (unsigned) mStop);
307 }
308 
310  return (mWavetable.mNumFrames == duration());
311 }
312 
313 ///< answer if file has X samples in RAM
314 
315 bool Abst_SoundFile::isCached(unsigned samps) {
316 // logMsg("isCached : %d > %d + %d", mWavetable.mNumFrames, mCurrentFrame, samps);
317  return (mWavetable.mNumFrames >= (mCurrentFrame + samps));
318 }
319 
320 // trigger the file to start
321 
323  if (mStart > 0) {
325  seekTo(mStart);
326  } else {
327  mCurrentFrame = 0;
328  seekTo(0);
329  }
330 }
331 
332 // set the pointer to the end of the file
333 
336 }
337 
338 // Read the ID3 tags. Returns true if able to read them from the file
339 
341 #ifdef USE_TAGS
342  if ( ! mProperties)
344  TagLib::FileRef tfil(mPath.c_str());
345  if ( ! tfil.isNull() && tfil.tag()) {
346  TagLib::Tag *tag = tfil.tag();
347  mProperties->mTitle = string(tag->title().toCString());
348  mProperties->mArtist = string(tag->artist().toCString());
349  mProperties->mAlbum = string(tag->album().toCString());
350  mProperties->mYear = tag->year();
351  mProperties->mComment = string(tag->comment().toCString());
352  mProperties->mTrack = tag->track();
353  mProperties->mGenre = string(tag->genre().toCString());
354  }
355  if( ! tfil.isNull() && tfil.audioProperties()) {
356  TagLib::AudioProperties *properties = tfil.audioProperties();
357  mProperties->mBitRate = properties->bitrate();
358  mProperties->mSampleRate= properties->sampleRate();
359  mProperties->mChannels = properties->channels();
360  mProperties->mLength = properties->length();
361  }
362  return !tfil.isNull();
363 #else
364  return false;
365 #endif
366 }
367 
368 // log snd file props
369 
371  const char * nam = path().c_str();
372  if (strlen(nam) > 50)
373  logMsg("SndFile \"%s\"\n\t\t%d Hz, %d ch, %5.3f sec",
374  nam, frameRate(), channels(), durationInSecs());
375  else
376  logMsg("SndFile \"%s\" - %d Hz, %d ch, %5.3f sec",
377  path().c_str(), frameRate(), channels(), durationInSecs());
378 }
379 
380 ////////////// next_buffer -- the work is done here //////////
381 
382 void Abst_SoundFile::nextBuffer(Buffer &outputBuffer) throw(CException) {
383  unsigned numFrames = outputBuffer.mNumFrames;
384  unsigned currentFrame = mCurrentFrame;
385  DECLARE_SCALABLE_CONTROLS; // declare the scale/offset buffers and values
386 
387  if (currentFrame >= (unsigned) mStop) { // if done
388  outputBuffer.zeroBuffers();
389  return;
390  }
391  if (currentFrame + numFrames >= (unsigned) mStop) { // if final window
392  numFrames = mStop - currentFrame;
393  outputBuffer.zeroBuffers();
394  }
395  if ( ! this->isCached(numFrames)) { // if not playing from cache buffer
396  this->readBufferFromFile(numFrames); // read from file
397  }
398 
399  LOAD_SCALABLE_CONTROLS; // load the scaleC and offsetC from the constant or dynamic value
400 
401  if (mRate == 1) { // if playing at normal rate
402  if (scalePort->isFixed() && offsetPort->isFixed() // if fixed scale/offset, use memcpy
403  && (scaleValue == 1) && (offsetValue == 0)) {
404  unsigned numBytes = numFrames * sizeof(sample); // buffer copy loop
405  for (unsigned i = 0; i < outputBuffer.mNumChannels; i++) {
406  int which = csl_min(i, (mNumChannels - 1));
407  SampleBuffer sndPtr = mWavetable.buffer(which) + currentFrame;
408  SampleBuffer outPtr = outputBuffer.buffer(i);
409  memcpy(outPtr, sndPtr, numBytes); // here's the memcpy
410  }
411  } else { // else loop applying scale/offset
412  sample samp;
413  for (unsigned i = 0; i < outputBuffer.mNumChannels; i++) {
414  SampleBuffer buffer = outputBuffer.buffer(i); // get pointer to the selected output channel
415  SampleBuffer dPtr = mWavetable.buffer(csl_min(i, (mNumChannels - 1))) + currentFrame;
416  for (unsigned j = 0; j < numFrames; j++) { // here's the sample loop
417  samp = (*dPtr++ * scaleValue) + offsetValue; // get and scale the file sample
418  *buffer++ = samp;
419  UPDATE_SCALABLE_CONTROLS; // update the dynamic scale/offset
420  }
421  scalePort->resetPtr();
422  offsetPort->resetPtr();
423  }
424  }
425  } else { // if mRate != 1.0,
426  // use wavetable interpolation
427  this->setFrequency(mRate);
428  for (unsigned i = 0; i < mNumChannels; i++)
429  WavetableOscillator::nextBuffer(outputBuffer, i);
430  }
431  currentFrame += numFrames; // increment buf ptr
432  if ((currentFrame >= (unsigned) mStop) && mIsLooping) // if we are past the end of the file...
433  currentFrame = 0; // this will click, have to call nextBuffer() recursively here
434  mCurrentFrame = currentFrame; // store back to member
435  return;
436 }
437 
438 
439 ////////////////////////////////////////////////////////////////////////////////////////////
440 //
441 // Sound Cue implementation
442 //
443 
444 // Generic constructors
445 
447  mFile = NULL;
448  mCurrent = 0;
449 }
450 
451 SoundCue::SoundCue(string name, Abst_SoundFile *file, int start, int stop) :
452  mName(name),
453  mFile(file),
454  mStart(start),
455  mStop(stop) {
456  mCurrent = mStart;
457  mReadRate = (UnitGenerator*) 0;
458 }
459 
461 
462 // Read an instance's data from a file
463 // The format is that used in the SeSpSp layer index file:
464 // name start stop
465 // b5b.r21e.aiff 13230080 15876096 -- NB: these are in FRAMES
466 
467 void SoundCue::readFrom (FILE *input) {
468  char cmName[128];
469  unsigned start, stop;
470 
471  if(fscanf(input, "%s %u %u\n", cmName, &start, &stop) == 3) {
472  mName = cmName;
473  mStart = start;
474  mStop = stop;
475  mCurrent = mStart;
476  }
477 }
478 
479 // Pretty-print the receiver
480 
482  logMsg("\tSC: \"%s\" %d - %d (%.3f)\n",
483  mName.c_str(), mStart, mStop,
484  ((float)(mStop - mStart) / (float)(mFile->frameRate() * mFile->channels())));
485 }
486 
487 // Copy samples from the file's sample buffer to the output
488 // I assume that the # of channels in the output is the same as in my file, i.e.,
489 // To play a mono file, "wrap" it in a Deinterleaver
490 
491 void SoundCue::nextBuffer(Buffer &outputBuffer) throw(CException) {
492  unsigned numFrames = outputBuffer.mNumFrames;
493  unsigned toCopy = 0, toZero;
494  SampleBuffer out;
495 
496  for (unsigned h = 0; h < outputBuffer.mNumChannels; h++) {
497  out = outputBuffer.buffer(h);
498  if (mCurrent >= mStop) { // if done
499  for (unsigned i = 0; i < numFrames; i++)
500  *out++ = 0.0;
501  continue;
502  }
503  SampleBuffer samps = (mFile->mWavetable.buffer(0)) + (mCurrent * mFile->channels()) + h;
504  if ( ! mFile->isValid()) { // if no file data
505  fprintf(stderr, "\tCannot play uncached sound file \"%s\"n", mName.c_str());
506  for (unsigned i = 0; i < numFrames; i++)
507  *out++ = 0.0;
508  continue;
509  }
510  toCopy = numFrames; // figure out how many samples to copy
511  toZero = 0;
512  if ((mCurrent + numFrames) >= (unsigned) mStop) {
513  toCopy = mStop - mCurrent;
514  toZero = numFrames - toCopy;
515  // fprintf(stderr, "\tSample \"%s\" finished\n", mName);
516  } // Now do the copy loops
517  for (unsigned i = 0; i < toCopy; i++)
518  *out++ = *samps++;
519  for (unsigned i = 0; i < toZero; i++)
520  *out++ = 0.0;
521  }
522  mCurrent += toCopy; // increment the receiver's sample pointer
523  return;
524 }
525 
526 // Utility functions
527 
529  if (mFile == 0)
530  return (false);
531  return (mCurrent < mStop);
532 }
533 
534 void SoundCue::setToEnd(void) {
535  mCurrent = mStop;
536 }
537 
538 void SoundCue::trigger(void) {
539  mCurrent = mStart;
540  mFloatCurrent = 0.0;
541 }
542 
543 #ifdef USE_SNDFILEBUFFER
544 
545 ////////////////////////////////////////////////////////////////////////////////////////////
546 //
547 // SoundFileBuffer implementation
548 //
549 
550 #ifdef USE_JSND
551  #include "SoundFileJ.h"
552  #define SoundFile JSoundFile // JUCE snd file class
553 #endif
554 
555 #ifdef USE_LSND
556  #include "SoundFileL.h"
557  #define SoundFile LSoundFile // LibSndFile snd file class
558 #endif
559 
560 #ifdef USE_CASND
561  #include "SoundFileCA.h"
562  #define SoundFile CASoundFile // CoreAudio snd file class
563 #endif
564 
565 SoundFileBuffer::SoundFileBuffer(string path, unsigned numFrames)
566  : Buffer(CGestalt::numOutChannels(), numFrames) {
567  mFile = (Abst_SoundFile * ) (new SoundFile(path));
568  mFile->openForRead(false);
571  mNumFrames = mFile->duration();
572  mNumAlloc = csl_min(CGestalt::sndFileFrames(), mNumFrames);
573  mMonoBufferByteSize = mNumFrames * mNumChannels * sizeof(sample);
574  mAreBuffersAllocated = true;
575  mDidIAllocateBuffers = false;
576 
577  mBuffers = new SampleBuffer[mNumChannels]; // reserve space for buffers
578  for (unsigned i = 0; i < mNumChannels; i++)
579  setBuffer(i, mFile->buffer(i));
580 }
581 
582 ///< Copy constructor -- shares sample buffer
583 
584 SoundFileBuffer::SoundFileBuffer(Abst_SoundFile & otherSndFile) {
585  // setBuffer
586 }
587 
588 SoundFileBuffer::~SoundFileBuffer() { }
589 
590 
591 /// answer a samp ptr, testing that it's in RAM
592 
593 sample * SoundFileBuffer::samplePtrFor(unsigned channel, unsigned offset){
594  if ((mFile->base() <= offset) && (mFile->base() + mFile->cacheSize() > offset))
595  return(mFile->mWavetable.buffer(channel) + (offset - mFile->base()));
596  if (mFile) {
597  mFile->seekTo(offset);
598  mFile->readBufferFromFile(mFile->mWavetable.mNumFrames);
599  return(mFile->mWavetable.buffer(channel));
600  }
601  return NULL;
602 }
603 
604 /// answer a samp ptr tested for extent (offset + maxFrame)
605 
606 sample * SoundFileBuffer::samplePtrFor(unsigned channel, unsigned offset, unsigned maxFrame){
607  if ((mFile->base() <= offset) && ((mFile->base() + mNumAlloc) > (offset + maxFrame)))
608  return (mFile->mWavetable.buffer(channel) + (offset - mFile->base()));
609  if (mFile) {
610  mFile->seekTo(offset);
611  mFile->readBufferFromFile(mFile->mWavetable.mNumFrames);
612  return(mFile->mWavetable.buffer(channel));
613  }
614  return NULL;
615 }
616 
617 #endif
618 
619 #ifdef UNDEFINED
620 
621 //class SampleFile : public Abst_SoundFile {
622 //public:
623 // SampleFile(); /// Constructor
624 // SampleFile(string name, Abst_SoundFile *file = 0, int start = 1, int stop = -1);
625 // ~SampleFile();
626 // /// Data members
627 // unsigned mMIDIKey; // sample's MIDI key #
628 // double mFrequency; // sample's actual frequency
629 // double mMinRatio; // min transp.
630 // double mMaxRatio; // max transp. (often 1.0)
631 //
632 // double ratioForKey(int desiredMIDI);
633 // double ratioForPitch(int desiredMIDI);
634 
635 SampleFile::SampleFile() {
636 
637 }
638 
639 SampleFile::SampleFile(string tpath, unsigned MIDIKey, double frequency, double minRatio, double maxRatio) {
640 
641 }
642 
643 SampleFile::~SampleFile() {
644 
645 }
646 
647 #endif
sample * SampleBuffer
1-channel buffer data type, vector of (sample)
Definition: CSL_Types.h:194
#define UPDATE_SCALABLE_CONTROLS
Definition: CSL_Core.h:444
void logMsg(const char *format,...)
These are the public logging messages.
Definition: CGestalt.cpp:292
UnitGenerator * mReadRate
my playback rate
Definition: SoundFile.h:214
void setStart(int val)
Definition: SoundFile.cpp:248
#define kSoundFileFormatAIFF
Definition: SoundFile.h:60
unsigned mNumFrames
num frames used in each buffer
Definition: CSL_Core.h:113
const char * gSndFileExts[]
Sound file name extensions we recognize - ToDo: should this be in a config file?
Definition: SoundFile.cpp:40
unsigned mNumFrames
sample frames
Definition: SoundFile.h:189
virtual void setBuffer(unsigned bufNum, SampleBuffer sPtr)
Definition: CSL_Core.h:158
unsigned frameRate()
Definition: CSL_Core.h:249
#define csl_min(a, b)
double mRate
sample rate ratio
Definition: SoundFile.h:188
csl::Status convertRate(int fromRate, int toRate)
convert the sample rate using libSampleRate
bool mAreBuffersAllocated
are the buffers allocated?
Definition: CSL_Core.h:120
bool isActive()
answer if currently active
Definition: SoundFile.cpp:303
AdditiveInstrument.h – Sum-of-sines synthesis instrument class.
Definition: Accessor.h:17
static unsigned sndFileFrames()
the default num frames that are cached
Definition: CGestalt.cpp:55
static const char * mimeType(const char *path)
Answer the MIME type based on the file name.
Definition: SoundFile.cpp:98
WavetableOscillator – Oscillator with a stored wave table that does table look-up. The default wave table is an 8192-sample sine. (perhaps accept a vector of freqs and a multichannel buffer?)
Definition: Oscillator.h:66
static SoundFileFormat sndfileNameType(const char *path)
Answer the snd file type.
Definition: SoundFile.cpp:60
unsigned mFrameRate
trigger ignored here
Definition: CSL_Core.h:288
unsigned mBase
starting frame in file of buffer
Definition: SoundFile.h:191
void mergeToMono()
average all the channels to mono
Definition: SoundFile.cpp:208
virtual void readBufferFromFile(unsigned numFr)=0
int SoundFileFormat
Definition: SoundFile.h:65
virtual unsigned seekTo(int position, SeekPosition whence)=0
seek to some position relative to "whence"
virtual void setToEnd()
set to end position
Definition: SoundFile.cpp:334
unsigned mBitRate
encoding data
Definition: SoundFile.h:82
virtual SampleBuffer buffer(unsigned bufNum)
convenience accessors for sample buffers
Definition: CSL_Core.cpp:66
virtual void nextBuffer(Buffer &outputBuffer, unsigned outBufNum)
really compute the next buffer given an offset base channel; this is called by nextBuffer, possibly multiple times
Definition: Oscillator.cpp:132
virtual void setPath(string path)
set file name path string
Definition: SoundFile.cpp:153
Abst_SoundFile * mFile
the file I point into
Definition: SoundFile.h:212
string path()
file name
Definition: SoundFile.h:158
void dump(void)
pretty-print me UGen operations
Definition: SoundFile.cpp:481
float mFloatCurrent
current pointer as a float
Definition: SoundFile.h:228
std::string mComment
Definition: SoundFile.h:78
void setStop(int val)
Definition: SoundFile.cpp:266
virtual void trigger()
reset to start
Definition: SoundFile.cpp:322
Class SndFileMetadata holds the ID3 tags of a sound file.
Definition: SoundFile.h:72
void copyFrom(Buffer &src)
Definition: CSL_Core.cpp:250
void freeBuffers()
fcn to free them
Definition: CSL_Core.cpp:141
The CSL system defaults class.
Definition: CGestalt.h:39
void setToEnd(void)
Definition: SoundFile.cpp:534
void setSize(unsigned numChannels, unsigned numFrames)
Definition: CSL_Core.cpp:75
void setStopRatio(float val)
Definition: SoundFile.cpp:279
bool mIsValid
is my file valid?
Definition: SoundFile.h:185
Abst_SoundFile(string path, int start=-1, int stop=-1)
Constructor. Values not passed default to null.
Definition: SoundFile.cpp:111
#define kSoundFileFormatSND
Definition: SoundFile.h:61
void readFrom(FILE *input)
for loading file lists
Definition: SoundFile.cpp:467
bool isActive()
query whether I'm currently active (Envelopes can go inactive)
Definition: SoundFile.cpp:528
int mCurrent
the start/stop samples I represent
Definition: SoundFile.h:213
#define kSoundFileFormatOther
Definition: SoundFile.h:64
unsigned mCurrentFrame
where I currently am in the buffer
Definition: CSL_Core.h:580
float sample
(could be changed to int, or double)
Definition: CSL_Types.h:191
unsigned mNumChannels
my "expected" number of output channels
Definition: CSL_Core.h:292
#define kSoundFileFormatWAV
Definition: SoundFile.h:59
virtual void freeBuffer()
free the file cache
Definition: SoundFile.cpp:165
virtual void openForRead(bool load=true)=0
std::string mAlbum
Definition: SoundFile.h:76
void trigger(void)
Definition: SoundFile.cpp:538
Writeable – a mix-in for buffers and streams that one can write to.
Definition: CSL_Core.h:546
void nextBuffer(Buffer &outputBuffer)
copy next buffer from cache
Definition: SoundFile.cpp:491
bool readTags()
read the ID3 or other tags. Returns true if able to read them.
Definition: SoundFile.cpp:340
static bool isSndfileName(const char *path)
Answer whether the given name looks like a snd file.
Definition: SoundFile.cpp:44
int mStop
starting/ending frames (or -1 if not used)
Definition: SoundFile.h:187
virtual void nextBuffer(Buffer &outB)
UGen operations are implemented here copy next buffer from file cache.
Definition: SoundFile.cpp:382
void setWaveform(Buffer &wave, bool freeBufs=true)
plug in waveforms set the interpolation flag
Definition: Oscillator.cpp:76
virtual SampleBuffer buffer(unsigned bufNum)
Definition: SoundFile.h:134
Buffer mWavetable
the stored wave form
Definition: Oscillator.h:84
void setStartRatio(float val)
Definition: SoundFile.cpp:262
#define CSL_WORD_LEN
default short string length
Definition: CSL_Types.h:119
string mPath
file name
Definition: SoundFile.h:182
std::string mTitle
ID3 tag fields.
Definition: SoundFile.h:74
unsigned duration()
Definition: SoundFile.h:138
#define LOAD_SCALABLE_CONTROLS
Load the scale/offset-related values at the start.
Definition: CSL_Core.h:436
void setBase(int val)
Definition: SoundFile.cpp:283
bool mDidIAllocateBuffers
who allocated my data buffers?
Definition: CSL_Core.h:121
#define CSL_RATE
Definition: CSL_Types.h:285
Buffer – the multi-channel sample buffer class (passed around between generators and IO guys)...
Definition: CSL_Core.h:106
virtual void dump()
log snd file props
Definition: SoundFile.cpp:370
void setStartSec(float val)
Definition: SoundFile.cpp:258
void convertRate(int fromRate, int toRate)
perform sample-rate conversion
Definition: SoundFile.cpp:236
void setRate(UnitGenerator &frequency)
set the receiver's playback rate (pitch ratio)
Definition: SoundFile.cpp:289
void dump()
pretty-print the receiver
Definition: SoundFile.cpp:17
void allocateBuffers()
fcn to malloc storage buffers
Definition: CSL_Core.cpp:122
SoundFileMetadata * mProperties
the ID3 tags properties
Definition: SoundFile.h:179
void addInput(CSL_MAP_KEY name, UnitGenerator &ugen)
Plug in a unit generator to the named input slot.
Definition: CSL_Core.cpp:894
PortMap mInputs
the map of my inputs or controls (used by the mix-in classes)
Definition: CSL_Core.h:378
forward declaration
Definition: CSL_Core.h:241
void checkBuffer(unsigned numFrames)
allocate buffer lazily
Definition: SoundFile.cpp:172
string mName
my name
Definition: SoundFile.h:211
virtual bool isCached()
answer if file is loaded into RAM
Definition: SoundFile.cpp:309
std::string mGenre
Definition: SoundFile.h:80
std::string mArtist
Definition: SoundFile.h:75
Here's the abstract sound file reader/writer class, a sample player UGen. The concrete subclasses rep...
Definition: SoundFile.h:101
unsigned channels() const
accessors
Definition: SoundFile.cpp:157
Seekable – a mix-in for positionable streams.
Definition: CSL_Core.h:577
float durationInSecs()
number of frames in the sound file
Definition: SoundFile.cpp:161
Base class of CSL exceptions (written upper-case). Has a string message.
void setStopSec(float val)
Definition: SoundFile.cpp:275
#define DECLARE_SCALABLE_CONTROLS
Macros for all the Scalable UnitGenerators (note that these don't end with ";")
Definition: CSL_Core.h:429