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  //printf("framelen %d startframe %d endframe %d, sfinfo.frames %d\n",frameLen,startFrame,endFrame,sfinfo.frames);
34  cout << "Error: " << file << " invalid frame range requested" << endl;
35  return 1;
36  }
37 
38  sf_seek(sndfile,startFrame,SEEK_SET);
39 
40  float* tempBuf = new float[frameLen*numChannelsInFile];
41 
42  int subformat = sfinfo.format & SF_FORMAT_SUBMASK;
43  int readcount = sf_read_float(sndfile, tempBuf, frameLen*numChannelsInFile); //FIXME
44 
45  // Pad with zeros in case we couldn't read whole file
46  for(int k = readcount; k <frameLen*numChannelsInFile; k++)
47  tempBuf[k] = 0;
48 
49  if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE) {
50  double scale ;
51  int m ;
52 
53  sf_command (sndfile, SFC_CALC_SIGNAL_MAX, &scale, sizeof (scale)) ;
54  if (scale < 1e-10)
55  scale = 1.0 ;
56  else
57  scale = 32700.0 / scale ;
58  cout << "File samples scale = " << scale << endl;
59 
60  for (m = 0; m < frameLen; m++)
61  tempBuf[m] *= scale;
62  }
63 
64  for(int n=0;n<frameLen;n++)
65  buf[n] = tempBuf[n*numChannelsInFile+channel];
66 
67  sf_close(sndfile);
68 
69  return 0;
70 }
71 
72 int getNumChannels(string file) {
73 
74  SNDFILE *sndfile ;
75  SF_INFO sfinfo ;
76  sfinfo.format = 0;
77  if (!(sndfile = sf_open (file.c_str(), SFM_READ, &sfinfo))) {
78  cout << "Couldn't open file " << file << ": " << sf_strerror(sndfile) << endl;
79  return -1;
80  }
81 
82  return sfinfo.channels;
83 }
84 
85 int getNumFrames(string file) {
86 
87  SNDFILE *sndfile ;
88  SF_INFO sfinfo ;
89  sfinfo.format = 0;
90  if (!(sndfile = sf_open (file.c_str(), SFM_READ, &sfinfo))) {
91  cout << "Couldn't open file " << file << ": " << sf_strerror(sndfile) << endl;
92  return -1;
93  }
94 
95  return sfinfo.frames;
96 }
97 
Main Bela public API.