diff options
| author | Bent Bisballe Nyeng <deva@aasimon.org> | 2014-03-30 11:15:18 +0200 | 
|---|---|---|
| committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2014-03-30 11:15:18 +0200 | 
| commit | f271a3905a0e8d16f9258ba0b8743a8fd689e787 (patch) | |
| tree | 24b25ebbd7f73f281f9ab15a491797de7103a4d4 /dgedit | |
| parent | 63bf74ffaeb5580af677719485c40fe50e248f51 (diff) | |
Export as single file with multiple channels.
Diffstat (limited to 'dgedit')
| -rw-r--r-- | dgedit/audioextractor.cc | 179 | ||||
| -rw-r--r-- | dgedit/audioextractor.h | 2 | 
2 files changed, 95 insertions, 86 deletions
| diff --git a/dgedit/audioextractor.cc b/dgedit/audioextractor.cc index 9692b0b..8395b7f 100644 --- a/dgedit/audioextractor.cc +++ b/dgedit/audioextractor.cc @@ -32,111 +32,121 @@  #include <sndfile.h> +typedef struct { +  SNDFILE *fh; +  float *data; +} audiodata_t; +  AudioExtractor::AudioExtractor(QObject *parent)    : QObject(parent)  {  } -float *AudioExtractor::load(QString file, size_t *size) +void AudioExtractor::exportSelections(Selections selections, +                                      Levels levels)  { -  float *data; +  // Open all input audio files: +  audiodata_t audiodata[audiofiles.size()]; -  SF_INFO sf_info; -	SNDFILE *fh = sf_open(file.toStdString().c_str(), SFM_READ, &sf_info); -  if(!fh) { -    printf("Load error...\n"); -    *size = 0; -    return NULL; -  } - -  *size = sf_info.frames; - -  data = new float[*size]; - -	sf_read_float(fh, data, *size);  +  int idx = 0; +  AudioFileList::iterator j = audiofiles.begin(); +  while(j != audiofiles.end()) { +    QString file = j->first; -	sf_close(fh); +    SF_INFO sf_info; +    audiodata[idx].fh = sf_open(file.toStdString().c_str(), SFM_READ, &sf_info); +    if(!audiodata[idx].fh) { +      printf("Load error '%s'\n", file.toStdString().c_str()); +      return; +    } -  return data; -} +    audiodata[idx].data = NULL; -void AudioExtractor::exportSelection(QString filename, -                                     int index, -                                     float *data, size_t size, -                                     Selection sel) -{ -  printf("Writing: %s (sz: %d, from %d to %d)\n", -         filename.toStdString().c_str(), (int)size, sel.from, sel.to); -   -  if(sel.from > (int)size || -     sel.to > (int)size || -     sel.to < 0 || -     sel.from < 0 || -     sel.to < sel.from) { -    printf("Out of bounds\n"); -    return; +    j++; +    idx++;    } +   +  idx = 0; +  QMap<int, Selection>::iterator si = selections.begin(); +  while(si != selections.end()) { +    Selection &sel = *si; +    size_t offset = sel.from; +    size_t size = sel.to - sel.from; +    size_t fadein = sel.fadein; +    size_t fadeout = sel.fadeout; + + +    // Read all input audio file chunks: +    for(int i = 0; i < audiofiles.size(); i++) { + +      // Clear out old buffer (if one exists) +      if(audiodata[i].data) { +        delete audiodata[i].data; +        audiodata[i].data = NULL; +      } -  // Apply linear fadein -  for(int i = 0; i < sel.fadein; i++) { -    float val = ((float)i / (float)sel.fadein); -    data[i + sel.from] *= val; -  } +      SNDFILE *fh = audiodata[i].fh; -  // Apply fadeout -  for(int i = 0; i < sel.fadeout; i++) { -    float val = ((float)i / (float)sel.fadeout); -    data[sel.to - i] *= val; -  } +      sf_seek(fh, offset, SEEK_SET); -  SF_INFO sf_info; -  sf_info.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT; -  sf_info.samplerate = 44100; -  sf_info.channels = 1; +      float *data = new float[size]; +      sf_read_float(fh, data, size);  -  SNDFILE *fh = sf_open(filename.toStdString().c_str(), SFM_WRITE, &sf_info); -  if(!fh) { -    printf("Open for write error...\n"); -    return; -  } -  sf_write_float(fh, data + sel.from, sel.to - sel.from);  -  sf_close(fh); -} +      // Apply linear fadein +      for(size_t fi = 0; fi < fadein; fi++) { +        float val = ((float)fi / (float)fadein); +        data[fi] *= val; +      } -void AudioExtractor::exportSelections(Selections selections, -                                      Levels levels) -{ -  // Do the actual exporting one file at the time. -  AudioFileList::iterator j = audiofiles.begin(); -  while(j != audiofiles.end()) { +      // Apply fadeout +      for(size_t fo = 0; fo < fadeout; fo++) { +        float val = ((float)fo / (float)fadeout); +        data[size - fo] *= val; +      } -    QString file = j->first; -    QString name = j->second; -    size_t size; +      audiodata[i].data = data; +    } -    // TODO: Use sf_seek instead... -    float *data = load(file, &size); -    if(!data) continue; +    // Create output path: +    QString path = exportpath + "/" + prefix + "/samples"; +    QDir d; +    d.mkpath(path); -    int index = 0; -    QMap<int, Selection>::iterator i = selections.begin(); -    while(i != selections.end()) { -      index++; +    // Write all sample chunks to single output file: +    QString file = path + "/" + QString::number(idx) + "-" + prefix + ".wav"; +     +    SF_INFO sf_info; +    sf_info.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT; +    sf_info.samplerate = 44100; +    sf_info.channels = audiofiles.size(); + +    SNDFILE *ofh = sf_open(file.toStdString().c_str(), SFM_WRITE, &sf_info); +    if(!ofh) { +      printf("Open for write error...\n"); +      return; +    } -      QString path = exportpath + "/" + prefix + "/samples"; -      QString file = path + "/" + QString::number(index) + -        "-" + prefix + "-" + name + ".wav"; +    for(size_t ob = 0; ob < size; ob++) { +      float obuf[audiofiles.size()]; +      for(int ai = 0; ai < audiofiles.size(); ai++) { +        obuf[ai] = audiodata[ai].data[ob]; +      } +      sf_write_float(ofh, obuf, audiofiles.size());  +    } +    sf_close(ofh); -      QDir d; -      d.mkpath(path); +    idx++; +    si++; +  } -      exportSelection(file, index, data, size, i.value()); -      i++; +  // Close all input audio files: +  for(int i = 0; i < audiofiles.size(); i++) { +    if(audiodata[i].data) { +      delete audiodata[i].data; +      audiodata[i].data = NULL;      } -    delete[] data; -     -    j++; +    sf_close(audiodata[i].fh);    }    QDomDocument doc; @@ -164,6 +174,7 @@ void AudioExtractor::exportSelections(Selections selections,      sample.setAttribute("power", QString::number(i->energy));      samples.appendChild(sample); +    int channelnum = 1; // Filechannel numbers are 1-based.      AudioFileList::iterator j = audiofiles.begin();      while(j != audiofiles.end()) { @@ -172,11 +183,11 @@ void AudioExtractor::exportSelections(Selections selections,        QDomElement audiofile = doc.createElement("audiofile");        audiofile.setAttribute("file", "samples/" +  -                             QString::number(index) + "-" + prefix + -                             "-" + name + ".wav"); +                             QString::number(index) + "-" + prefix + ".wav");        audiofile.setAttribute("channel", name); +      audiofile.setAttribute("filechannel", QString::number(channelnum));        sample.appendChild(audiofile); - +      channelnum++;        j++;      } diff --git a/dgedit/audioextractor.h b/dgedit/audioextractor.h index 33ccf71..f18860b 100644 --- a/dgedit/audioextractor.h +++ b/dgedit/audioextractor.h @@ -52,8 +52,6 @@ public slots:    void setOutputPrefix(const QString &prefix);  private: -  float *load(QString file, size_t *size); -  void exportSelection(QString name, int index, float *data, size_t size, Selection sel);    AudioFileList audiofiles;    QString exportpath;    QString prefix; | 
