Bela
Real-time, ultra-low-latency audio and sensor processing system for BeagleBone Black
 All Classes Files Functions Variables Typedefs Macros Groups
SampleLoader.h
1 /***** SampleLoader.h *****/
2 
3 #include <Bela.h>
4 #include <sndfile.h> // to load audio files
5 #include <string>
6 #include <iostream>
7 #include <cstdlib>
8 
9 using namespace std;
10 
11 // Load samples from file
12 int getSamples(string file, float *buf, int channel, int startFrame, int endFrame)
13 {
14  SNDFILE *sndfile ;
15  SF_INFO sfinfo ;
16  sfinfo.format = 0;
17  if (!(sndfile = sf_open (file.c_str(), SFM_READ, &sfinfo))) {
18  cout << "Couldn't open file " << file << ": " << sf_strerror(sndfile) << endl;
19  return 1;
20  }
21 
22  int numChannelsInFile = sfinfo.channels;
23  if(numChannelsInFile < channel+1)
24  {
25  cout << "Error: " << file << " doesn't contain requested channel" << endl;
26  return 1;
27  }
28 
29  int frameLen = endFrame-startFrame;
30 
31  if(frameLen <= 0 || startFrame < 0 || endFrame <= 0 || endFrame > sfinfo.frames)
32  {
33  cout << "Error: " << file << " invalid frame range requested" << endl;
34  return 1;
35  }
36 
37  sf_seek(sndfile,startFrame,SEEK_SET);
38 
39  float* tempBuf = new float[frameLen*numChannelsInFile];
40 
41  int subformat = sfinfo.format & SF_FORMAT_SUBMASK;
42  int readcount = sf_read_float(sndfile, tempBuf, frameLen*numChannelsInFile); //FIXME
43 
44  // Pad with zeros in case we couldn't read whole file
45  for(int k = readcount; k <frameLen*numChannelsInFile; k++)
46  tempBuf[k] = 0;
47 
48  if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE) {
49  double scale ;
50  int m ;
51 
52  sf_command (sndfile, SFC_CALC_SIGNAL_MAX, &scale, sizeof (scale)) ;
53  if (scale < 1e-10)
54  scale = 1.0 ;
55  else
56  scale = 32700.0 / scale ;
57  cout << "File samples scale = " << scale << endl;
58 
59  for (m = 0; m < frameLen; m++)
60  tempBuf[m] *= scale;
61  }
62 
63  for(int n=0;n<frameLen;n++)
64  buf[n] = tempBuf[n*numChannelsInFile+channel];
65 
66  sf_close(sndfile);
67 
68  return 0;
69 }
70 
71 int getNumChannels(string file) {
72 
73  SNDFILE *sndfile ;
74  SF_INFO sfinfo ;
75  sfinfo.format = 0;
76  if (!(sndfile = sf_open (file.c_str(), SFM_READ, &sfinfo))) {
77  cout << "Couldn't open file " << file << ": " << sf_strerror(sndfile) << endl;
78  return -1;
79  }
80 
81  return sfinfo.channels;
82 }
83 
84 int getNumFrames(string file) {
85 
86  SNDFILE *sndfile ;
87  SF_INFO sfinfo ;
88  sfinfo.format = 0;
89  if (!(sndfile = sf_open (file.c_str(), SFM_READ, &sfinfo))) {
90  cout << "Couldn't open file " << file << ": " << sf_strerror(sndfile) << endl;
91  return -1;
92  }
93 
94  return sfinfo.frames;
95 }
96 
Main Bela public API.