From 75702e36ddb30ca2924cb42dc0b44ddfbdac36e5 Mon Sep 17 00:00:00 2001
From: Bent Bisballe Nyeng <deva@aasimon.org>
Date: Sun, 23 Feb 2014 09:41:01 +0100
Subject: Apllied new multichannel audiofile feature patch from John Hammen.

---
 src/audiofile.cc        | 29 +++++++++++++++++++++++++++--
 src/audiofile.h         |  3 ++-
 src/instrumentparser.cc | 12 ++++++++++--
 3 files changed, 39 insertions(+), 5 deletions(-)

(limited to 'src')

diff --git a/src/audiofile.cc b/src/audiofile.cc
index 455bab0..05b356a 100644
--- a/src/audiofile.cc
+++ b/src/audiofile.cc
@@ -23,6 +23,8 @@
  *  You should have received a copy of the GNU General Public License
  *  along with DrumGizmo; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+ *
+ *  Multichannel feature by John Hammen copyright 2014
  */
 #include "audiofile.h"
 
@@ -39,10 +41,11 @@
 
 #include <config.h>
 
-AudioFile::AudioFile(std::string filename)
+AudioFile::AudioFile(std::string filename, int filechannel)
 {
   is_loaded = false;
   this->filename = filename;
+  this->filechannel = filechannel;
 
   data = NULL;
   size = 0;
@@ -91,6 +94,8 @@ void AudioFile::unload()
 #endif/*LAZYLOAD*/
 }
 
+#define	BUFFER_SIZE	4092
+
 void AudioFile::load(int num_samples)
 {
   // Make sure we don't unload the object while loading it...
@@ -123,7 +128,27 @@ void AudioFile::load(int num_samples)
   }
 
   sample_t* data = new sample_t[size]; 
-  size = sf_read_float(fh, data, size); 
+  if(sf_info.channels == 1) {
+    size = sf_read_float(fh, data, size);
+  }
+  else {
+    // check filechannel exists
+    if(filechannel >= sf_info.channels) {
+        filechannel = sf_info.channels - 1;
+    }
+    sample_t buffer[BUFFER_SIZE];
+    int readsize = BUFFER_SIZE / sf_info.channels;
+    int totalread = 0;
+    int read;
+    do {
+      read = sf_readf_float(fh, buffer, readsize);
+      for (int i = 0; i < read; i++) {
+        data[totalread++] = buffer[i * sf_info.channels + filechannel];
+      }
+    } while(read > 0 && totalread < (int)size);
+    // set data size to total bytes read
+    size = totalread;
+  }
   
   DEBUG(audiofile,"Loaded %d samples %p\n", (int)size, this);
   
diff --git a/src/audiofile.h b/src/audiofile.h
index 8a190c1..98bf101 100644
--- a/src/audiofile.h
+++ b/src/audiofile.h
@@ -71,7 +71,7 @@
 
 class AudioFile {
 public:
-  AudioFile(std::string filename);
+  AudioFile(std::string filename, int filechannel);
   ~AudioFile();
 
   void load(int num_samples = ALL_SAMPLES);
@@ -101,6 +101,7 @@ public:
 private:
   void *magic;
   volatile bool is_loaded;
+  int filechannel;
 };
 
 #endif/*__DRUMGIZMO_AUDIOFILE_H__*/
diff --git a/src/instrumentparser.cc b/src/instrumentparser.cc
index 454877f..6580b09 100644
--- a/src/instrumentparser.cc
+++ b/src/instrumentparser.cc
@@ -97,8 +97,16 @@ void InstrumentParser::startTag(std::string name,
       DEBUG(instrparser,"Missing required attribute 'channel'.\n");
       return;
     }
-
-    AudioFile *af = new AudioFile(path + "/" + attr["file"]);
+    int filechannel = 1; // default, override with optional attribute
+    if(attr.find("filechannel") != attr.end()) {
+        filechannel = atoi(attr["filechannel"].c_str());
+        if(filechannel < 1) {
+            DEBUG(instrparser,"Invalid value for attribute 'filechannel'.\n");
+            filechannel = 1;
+        }
+    }
+    filechannel = filechannel - 1; // 1-based in file, but zero-based internally
+    AudioFile *af = new AudioFile(path + "/" + attr["file"], filechannel);
     InstrumentChannel *ch = new InstrumentChannel(attr["channel"]);
     channellist.push_back(ch);
     s->addAudioFile(ch, af);
-- 
cgit v1.2.3