summaryrefslogtreecommitdiff
path: root/attic/muse2-oom/muse2/muse/wave.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'attic/muse2-oom/muse2/muse/wave.cpp')
-rw-r--r--attic/muse2-oom/muse2/muse/wave.cpp1176
1 files changed, 0 insertions, 1176 deletions
diff --git a/attic/muse2-oom/muse2/muse/wave.cpp b/attic/muse2-oom/muse2/muse/wave.cpp
deleted file mode 100644
index b519ca70..00000000
--- a/attic/muse2-oom/muse2/muse/wave.cpp
+++ /dev/null
@@ -1,1176 +0,0 @@
-//=========================================================
-// MusE
-// Linux Music Editor
-// $Id: wave.cpp,v 1.19.2.20 2009/12/20 05:00:35 terminator356 Exp $
-//
-// (C) Copyright 2000-2004 Werner Schweer (ws@seh.de)
-//=========================================================
-
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <cmath>
-
-#include <QDateTime>
-#include <QFileInfo>
-#include <QMessageBox>
-#include <QProgressDialog>
-
-#include "xml.h"
-#include "song.h"
-#include "wave.h"
-#include "app.h"
-#include "filedialog.h"
-#include "arranger/arranger.h"
-#include "globals.h"
-#include "event.h"
-#include "audio.h"
-///#include "sig.h"
-#include "al/sig.h"
-
-//#define WAVE_DEBUG
-//#define WAVE_DEBUG_PRC
-
-/*
-const char* audioFilePattern[] = {
- "Wave/Binary (*.wav *.ogg *.bin)",
- "Wave (*.wav *.ogg)",
- "Binary (*.bin)",
- "All Files (*)",
- 0
- };
-*/
-const int cacheMag = 128;
-
-// ClipList* waveClips;
-
-SndFileList SndFile::sndFiles;
-
-//---------------------------------------------------------
-// SndFile
-//---------------------------------------------------------
-
-SndFile::SndFile(const QString& name)
- {
- finfo = new QFileInfo(name);
- sf = 0;
- sfUI = 0;
- csize = 0;
- cache = 0;
- openFlag = false;
- sndFiles.push_back(this);
- refCount=0;
- }
-
-SndFile::~SndFile()
- {
- if (openFlag)
- close();
- for (iSndFile i = sndFiles.begin(); i != sndFiles.end(); ++i) {
- if (*i == this) {
- sndFiles.erase(i);
- break;
- }
- }
- delete finfo;
- if (cache) {
- for (unsigned i = 0; i < channels(); ++i)
- delete cache[i];
- delete[] cache;
- cache = 0;
- }
- }
-
-//---------------------------------------------------------
-// openRead
-//---------------------------------------------------------
-
-bool SndFile::openRead()
- {
- if (openFlag) {
- printf("SndFile:: alread open\n");
- return false;
- }
- QString p = path();
- sfinfo.format = 0;
- sf = sf_open(p.toLatin1().constData(), SFM_READ, &sfinfo);
- sfinfo.format = 0;
- sfUI = sf_open(p.toLatin1().constData(), SFM_READ, &sfinfo);
- if (sf == 0 || sfUI == 0)
- return true;
-
- writeFlag = false;
- openFlag = true;
- QString cacheName = finfo->absolutePath() + QString("/") + finfo->completeBaseName() + QString(".wca");
- readCache(cacheName, true);
- return false;
- }
-
-//---------------------------------------------------------
-// update
-// called after recording to file
-//---------------------------------------------------------
-
-void SndFile::update()
- {
- close();
-
- // force recreation of wca data
- QString cacheName = finfo->absolutePath() +
- QString("/") + finfo->completeBaseName() + QString(".wca");
- ::remove(cacheName.toLatin1().constData());
- if (openRead()) {
- printf("SndFile::update openRead(%s) failed: %s\n", path().toLatin1().constData(), strerror().toLatin1().constData());
- }
- }
-
-//---------------------------------------------------------
-// readCache
-//---------------------------------------------------------
-
-void SndFile::readCache(const QString& path, bool showProgress)
- {
-// printf("readCache %s for %d samples channel %d\n",
-// path.toLatin1().constData(), samples(), channels());
-
- if (cache) {
- for (unsigned i = 0; i < channels(); ++i)
- delete cache[i];
- delete[] cache;
- }
- if (samples() == 0) {
-// printf("SndFile::readCache: file empty\n");
- return;
- }
- csize = (samples() + cacheMag - 1)/cacheMag;
- cache = new SampleV*[channels()];
- for (unsigned ch = 0; ch < channels(); ++ch)
- cache[ch] = new SampleV[csize];
-
- FILE* cfile = fopen(path.toLatin1().constData(), "r");
- if (cfile) {
- for (unsigned ch = 0; ch < channels(); ++ch)
- fread(cache[ch], csize * sizeof(SampleV), 1, cfile);
- fclose(cfile);
- return;
- }
-
- //---------------------------------------------------
- // create cache
- //---------------------------------------------------
- QProgressDialog* progress = 0;
- if (showProgress) {
- QString label(QWidget::tr("create peakfile for "));
- label += basename();
- progress = new QProgressDialog(label,
- QString::null, 0, csize, 0);
- progress->setMinimumDuration(0);
- progress->show();
- }
- float data[channels()][cacheMag];
- float* fp[channels()];
- for (unsigned k = 0; k < channels(); ++k)
- fp[k] = &data[k][0];
- int interval = csize / 10;
-
- if(!interval)
- interval = 1;
- for (int i = 0; i < csize; i++) {
- if (showProgress && ((i % interval) == 0))
- progress->setValue(i);
- seek(i * cacheMag, 0);
- read(channels(), fp, cacheMag);
- for (unsigned ch = 0; ch < channels(); ++ch) {
- float rms = 0.0;
- cache[ch][i].peak = 0;
- for (int n = 0; n < cacheMag; n++) {
- float fd = data[ch][n];
- rms += fd * fd;
- int idata = int(fd * 255.0);
- if (idata < 0)
- idata = -idata;
- if (cache[ch][i].peak < idata)
- cache[ch][i].peak = idata;
- }
- // amplify rms value +12dB
- int rmsValue = int((sqrt(rms/cacheMag) * 255.0));
- if (rmsValue > 255)
- rmsValue = 255;
- cache[ch][i].rms = rmsValue;
- }
- }
- if (showProgress)
- progress->setValue(csize);
- writeCache(path);
- if (showProgress)
- delete progress;
- }
-
-//---------------------------------------------------------
-// writeCache
-//---------------------------------------------------------
-
-void SndFile::writeCache(const QString& path)
- {
- FILE* cfile = fopen(path.toLatin1().constData(), "w");
- if (cfile == 0)
- return;
- for (unsigned ch = 0; ch < channels(); ++ch)
- fwrite(cache[ch], csize * sizeof(SampleV), 1, cfile);
- fclose(cfile);
- }
-
-//---------------------------------------------------------
-// read
-//---------------------------------------------------------
-
-void SndFile::read(SampleV* s, int mag, unsigned pos, bool overwrite)
- {
- if(overwrite)
- for (unsigned ch = 0; ch < channels(); ++ch) {
- s[ch].peak = 0;
- s[ch].rms = 0;
- }
-
- if (pos > samples()) {
-// printf("%p pos %d > samples %d\n", this, pos, samples());
- return;
- }
-
- if (mag < cacheMag) {
- float data[channels()][mag];
- float* fp[channels()];
- for (unsigned i = 0; i < channels(); ++i)
- fp[i] = &data[i][0];
-
- sf_count_t ret = 0;
- if(sfUI)
- ret = sf_seek(sfUI, pos, SEEK_SET);
- else
- ret = sf_seek(sf, pos, SEEK_SET);
- if(ret == -1)
- return;
- {
- int srcChannels = channels();
- int dstChannels = sfinfo.channels;
- size_t n = mag;
- float** dst = fp;
- float buffer[n * dstChannels];
-
- size_t rn = 0;
- if(sfUI)
- rn = sf_readf_float(sfUI, buffer, n);
- else
- rn = sf_readf_float(sf, buffer, n);
- if(rn != n)
- return;
- float* src = buffer;
-
- if (srcChannels == dstChannels) {
- for (size_t i = 0; i < rn; ++i) {
- for (int ch = 0; ch < srcChannels; ++ch)
- *(dst[ch]+i) = *src++;
- }
- }
- else if ((srcChannels == 1) && (dstChannels == 2)) {
- // stereo to mono
- for (size_t i = 0; i < rn; ++i)
- *(dst[0] + i) = src[i + i] + src[i + i + 1];
- }
- else if ((srcChannels == 2) && (dstChannels == 1)) {
- // mono to stereo
- for (size_t i = 0; i < rn; ++i) {
- float data = *src++;
- *(dst[0]+i) = data;
- *(dst[1]+i) = data;
- }
- }
- }
-
- for (unsigned ch = 0; ch < channels(); ++ch) {
-
- if(overwrite)
- s[ch].peak = 0;
-
- float rms = 0.0;
- for (int i = 0; i < mag; i++) {
- float fd = data[ch][i];
- rms += fd;
- int idata = int(fd * 255.0);
- if (idata < 0)
- idata = -idata;
- if (s[ch].peak < idata)
- s[ch].peak = idata;
- }
-
- s[ch].rms = 0; // TODO rms / mag;
- }
- }
- else {
- mag /= cacheMag;
- int rest = csize - (pos/cacheMag);
- int end = mag;
- if (rest < mag)
- end = rest;
-
- for (unsigned ch = 0; ch < channels(); ++ch) {
- int rms = 0;
- int off = pos/cacheMag;
- for (int offset = off; offset < off+end; offset++) {
- rms += cache[ch][offset].rms;
- if (s[ch].peak < cache[ch][offset].peak)
- s[ch].peak = cache[ch][offset].peak;
- }
-
- if(overwrite)
- s[ch].rms = rms / mag;
-
- else
- s[ch].rms += rms / mag;
- }
- }
- }
-
-//---------------------------------------------------------
-// openWrite
-//---------------------------------------------------------
-
-bool SndFile::openWrite()
- {
- if (openFlag) {
- printf("SndFile:: alread open\n");
- return false;
- }
- QString p = path();
- sf = sf_open(p.toLatin1().constData(), SFM_RDWR, &sfinfo);
- sfUI = 0;
- if (sf) {
- openFlag = true;
- writeFlag = true;
- QString cacheName = finfo->absolutePath() +
- QString("/") + finfo->completeBaseName() + QString(".wca");
- readCache(cacheName, true);
- }
- return sf == 0;
- }
-
-//---------------------------------------------------------
-// close
-//---------------------------------------------------------
-
-void SndFile::close()
- {
- if (!openFlag) {
- printf("SndFile:: alread closed\n");
- return;
- }
- sf_close(sf);
- if (sfUI)
- sf_close(sfUI);
- openFlag = false;
- }
-
-//---------------------------------------------------------
-// remove
-//---------------------------------------------------------
-
-void SndFile::remove()
- {
- if (openFlag)
- close();
- QFile::remove(finfo->filePath());
- }
-
-QString SndFile::basename() const
- {
- return finfo->completeBaseName();
- }
-
-QString SndFile::path() const
- {
- return finfo->filePath();
- }
-
-QString SndFile::dirPath() const
- {
- return finfo->absolutePath();
- }
-
-QString SndFile::name() const
- {
- return finfo->fileName();
- }
-
-//---------------------------------------------------------
-// samples
-//---------------------------------------------------------
-
-unsigned SndFile::samples() const
- {
- if (!writeFlag) // if file is read only sfinfo is reliable
- return sfinfo.frames;
- sf_count_t curPos = sf_seek(sf, 0, SEEK_CUR);
- int frames = sf_seek(sf, 0, SEEK_END);
- sf_seek(sf, curPos, SEEK_SET);
- return frames;
- }
-
-//---------------------------------------------------------
-// channels
-//---------------------------------------------------------
-
-unsigned SndFile::channels() const
- {
- return sfinfo.channels;
- }
-
-unsigned SndFile::samplerate() const
- {
- return sfinfo.samplerate;
- }
-
-unsigned SndFile::format() const
- {
- return sfinfo.format;
- }
-
-void SndFile::setFormat(int fmt, int ch, int rate)
- {
- sfinfo.samplerate = rate;
- sfinfo.channels = ch;
- sfinfo.format = fmt;
- sfinfo.seekable = true;
- sfinfo.frames = 0;
- }
-
-//---------------------------------------------------------
-// readWithHeap
-// not as realtime friendly but can retrieve bigger data
-//---------------------------------------------------------
-size_t SndFile::readWithHeap(int srcChannels, float** dst, size_t n, bool overwrite)
- {
- float *buffer = new float[n * sfinfo.channels];
- int rn = readInternal(srcChannels,dst,n,overwrite, buffer);
- delete buffer;
- return rn;
- }
-
-//---------------------------------------------------------
-// read
-//---------------------------------------------------------
-size_t SndFile::read(int srcChannels, float** dst, size_t n, bool overwrite)
- {
- float buffer[n * sfinfo.channels];
- int rn = readInternal(srcChannels,dst,n,overwrite, buffer);
- return rn;
- }
-
-size_t SndFile::readInternal(int srcChannels, float** dst, size_t n, bool overwrite, float *buffer)
-{
- size_t rn = sf_readf_float(sf, buffer, n);
-
- float* src = buffer;
- int dstChannels = sfinfo.channels;
- if (srcChannels == dstChannels) {
- if(overwrite)
- for (size_t i = 0; i < rn; ++i) {
- for (int ch = 0; ch < srcChannels; ++ch)
- *(dst[ch]+i) = *src++;
- }
- else
- for (size_t i = 0; i < rn; ++i) {
- for (int ch = 0; ch < srcChannels; ++ch)
- *(dst[ch]+i) += *src++;
- }
- }
- else if ((srcChannels == 1) && (dstChannels == 2)) {
- // stereo to mono
- if(overwrite)
- for (size_t i = 0; i < rn; ++i)
- *(dst[0] + i) = src[i + i] + src[i + i + 1];
- else
- for (size_t i = 0; i < rn; ++i)
- *(dst[0] + i) += src[i + i] + src[i + i + 1];
- }
- else if ((srcChannels == 2) && (dstChannels == 1)) {
- // mono to stereo
- if(overwrite)
- for (size_t i = 0; i < rn; ++i) {
- float data = *src++;
- *(dst[0]+i) = data;
- *(dst[1]+i) = data;
- }
- else
- for (size_t i = 0; i < rn; ++i) {
- float data = *src++;
- *(dst[0]+i) += data;
- *(dst[1]+i) += data;
- }
- }
- else {
- printf("SndFile:read channel mismatch %d -> %d\n",
- srcChannels, dstChannels);
- }
-
- return rn;
-
-}
-
-
-//---------------------------------------------------------
-// write
-//
-// A hardcoded limiter was added that limits the output at 0.99/-0.99
-// libsndfile handles signal betwee -1.0/1.0 with current setting
-// outside these values there will be heavy distortion
-//
-//---------------------------------------------------------
-
-size_t SndFile::write(int srcChannels, float** src, size_t n)
- {
- int dstChannels = sfinfo.channels;
- //float buffer[n * dstChannels];
- float *buffer = new float[n * dstChannels];
- float *dst = buffer;
-
- const float limitValue=0.9999;
-
-
- if (srcChannels == dstChannels) {
- for (size_t i = 0; i < n; ++i) {
- for (int ch = 0; ch < dstChannels; ++ch)
- //*dst++ = *(src[ch]+i); // < limitValue ? *(src[ch]+i) : limitValue;
- if (*(src[ch]+i) > 0)
- *dst++ = *(src[ch]+i) < limitValue ? *(src[ch]+i) : limitValue;
- else
- *dst++ = *(src[ch]+i) > -limitValue ? *(src[ch]+i) : -limitValue;
- }
- }
- else if ((srcChannels == 1) && (dstChannels == 2)) {
- // mono to stereo
- for (size_t i = 0; i < n; ++i) {
- float data = *(src[0]+i);
- if (data > 0) {
- *dst++ = data < limitValue ? data : limitValue;
- *dst++ = data < limitValue ? data : limitValue;
- }
- else {
- *dst++ = data > -limitValue ? data : -limitValue;
- *dst++ = data > -limitValue ? data : -limitValue;
- }
- }
- }
- else if ((srcChannels == 2) && (dstChannels == 1)) {
- // stereo to mono
- for (size_t i = 0; i < n; ++i)
- if (*(src[0]+i) + *(src[1]+i) > 0)
- *dst++ = (*(src[0]+i) + *(src[1]+i)) < limitValue ? (*(src[0]+i) + *(src[1]+i)) : limitValue;
- else
- *dst++ = (*(src[0]+i) + *(src[1]+i)) > -limitValue ? (*(src[0]+i) + *(src[1]+i)) : -limitValue;
- }
- else {
- printf("SndFile:write channel mismatch %d -> %d\n",
- srcChannels, dstChannels);
- delete buffer;
- return 0;
- }
- int nbr = sf_writef_float(sf, buffer, n) ;
- delete buffer;
- return nbr;
- }
-
-//---------------------------------------------------------
-// seek
-//---------------------------------------------------------
-
-off_t SndFile::seek(off_t frames, int whence)
- {
- return sf_seek(sf, frames, whence);
- }
-
-//---------------------------------------------------------
-// strerror
-//---------------------------------------------------------
-
-QString SndFile::strerror() const
- {
- char buffer[128];
- buffer[0] = 0;
- sf_error_str(sf, buffer, 128);
- return QString(buffer);
- }
-
-//---------------------------------------------------------
-// search
-//---------------------------------------------------------
-
-SndFile* SndFileList::search(const QString& name)
- {
- for (iSndFile i = begin(); i != end(); ++i) {
- if ((*i)->path() == name)
- return *i;
- }
- return 0;
- }
-
-//---------------------------------------------------------
-// getSnd
-//---------------------------------------------------------
-
-SndFile* getWave(const QString& inName, bool readOnlyFlag)
- {
- QString name = inName;
-
- if (QFileInfo(name).isRelative()) {
- name = museProject + QString("/") + name;
- }
- else {
- if (!QFile::exists(name)) {
- if (QFile::exists(museProject + QString("/") + name)) {
- name = museProject + QString("/") + name;
- }
- }
- }
-// printf("=====%s %s\n", inName.toLatin1().constData(), name.toLatin1().constData());
-
- // only open one instance of wave file
- SndFile* f = SndFile::sndFiles.search(name);
- if (f == 0) {
- if (!QFile::exists(name)) {
- fprintf(stderr, "wave file <%s> not found\n",
- name.toLatin1().constData());
- return 0;
- }
- f = new SndFile(name);
- bool error;
- if (readOnlyFlag)
- error = f->openRead();
- else {
- error = f->openWrite();
- // if peak cache is older than wave file we reaquire the cache
- QFileInfo wavinfo(name);
- QString cacheName = wavinfo.absolutePath() + QString("/") + wavinfo.completeBaseName() + QString(".wca");
- QFileInfo wcainfo(cacheName);
- if (!wcainfo.exists() || wcainfo.lastModified() < wavinfo.lastModified()) {
- //printf("wcafile is older or does not exist!\n");
- QFile(cacheName).remove();
- f->readCache(cacheName,true);
- }
-
- }
- if (error) {
- fprintf(stderr, "open wave file(%s) for %s failed: %s\n",
- name.toLatin1().constData(),
- readOnlyFlag ? "writing" : "reading",
- f->strerror().toLatin1().constData());
- QMessageBox::critical(NULL, "MusE import error.",
- "MusE failed to import the file.\n"
- "Possibly this wasn't a sound file?\n"
- "If it was check the permissions, MusE\n"
- "sometimes requires write access to the file.");
-
- delete f;
- f = 0;
- }
- }
- else {
- if (!readOnlyFlag && ! f->isWritable()) {
- if (f->isOpen())
- f->close();
- f->openWrite();
- }
- else {
- // if peak cache is older than wave file we reaquire the cache
- QFileInfo wavinfo(name);
- QString cacheName = wavinfo.absolutePath() + QString("/") + wavinfo.completeBaseName() + QString(".wca");
- QFileInfo wcainfo(cacheName);
- if (!wcainfo.exists() || wcainfo.lastModified() < wavinfo.lastModified()) {
- //printf("wcafile is older or does not exist!\n");
- QFile(cacheName).remove();
- f->readCache(cacheName,true);
- }
-
- }
- }
- return f;
- }
-
-//---------------------------------------------------------
-// applyUndoFile
-//---------------------------------------------------------
-void SndFile::applyUndoFile(const QString& original, const QString& tmpfile, unsigned startframe, unsigned endframe)
- {
- // This one is called on both undo and redo of a wavfile
- // For redo to be called, undo must have been called first, and we don't store both the original data and the modified data in separate
- // files. Thus, each time this function is called the data in the "original"-file will be written to the tmpfile, after the data
- // from the tmpfile has been applied.
- //
- // F.ex. if mute has been made on part of a wavfile, the unmuted data is stored in the tmpfile when
- // the undo operation occurs. The unmuted data is then written back to the original file, and the mute data will be
- // put in the tmpfile, and when redo is eventually called the data is switched again (causing the muted data to be written to the "original"
- // file. The data is merely switched.
-
- //printf("Applying undofile: orig=%s tmpfile=%s startframe=%d endframe=%d\n", original.toLatin1().constData(), tmpfile.toLatin1().constData(), startframe, endframe);
- SndFile* orig = sndFiles.search(original);
- SndFile tmp = SndFile(tmpfile);
- if (!orig) {
- printf("Internal error: could not find original file: %s in filelist - Aborting\n", original.toLatin1().constData());
- return;
- }
-
- if (!orig->isOpen()) {
- if (orig->openRead()) {
- printf("Cannot open original file %s for reading - cannot undo! Aborting\n", original.toLatin1().constData());
- return;
- }
- }
-
- if (!tmp.isOpen()) {
- if (tmp.openRead()) {
- printf("Could not open temporary file %s for writing - cannot undo! Aborting\n", tmpfile.toLatin1().constData());
- return;
- }
- }
-
- audio->msgIdle(true);
- tmp.setFormat(orig->format(), orig->channels(), orig->samplerate());
-
- // Read data in original file to memory before applying tmpfile to original
- unsigned file_channels = orig->channels();
- unsigned tmpdatalen = endframe - startframe;
- float* data2beoverwritten[file_channels];
-
- for (unsigned i=0; i<file_channels; i++) {
- data2beoverwritten[i] = new float[tmpdatalen];
- }
- orig->seek(startframe, 0);
- orig->readWithHeap(file_channels, data2beoverwritten, tmpdatalen);
-
- orig->close();
-
- // Read data from temporary file to memory
- float* tmpfiledata[file_channels];
- for (unsigned i=0; i<file_channels; i++) {
- tmpfiledata[i] = new float[tmpdatalen];
- }
- tmp.seek(0, 0);
- tmp.readWithHeap(file_channels, tmpfiledata, tmpdatalen);
- tmp.close();
-
- // Write temporary data to original file:
- if (orig->openWrite()) {
- printf("Cannot open orig for write - aborting.\n");
- return;
- }
-
- orig->seek(startframe, 0);
- orig->write(file_channels, tmpfiledata, tmpdatalen);
-
- // Delete dataholder for temporary file
- for (unsigned i=0; i<file_channels; i++) {
- delete[] tmpfiledata[i];
- }
-
- // Write the overwritten data to the tmpfile
- if (tmp.openWrite()) {
- printf("Cannot open tmpfile for writing - redo operation of this file won't be possible. Aborting.\n");
- audio->msgIdle(false);
- return;
- }
- tmp.seek(0, 0);
- tmp.write(file_channels, data2beoverwritten, tmpdatalen);
- tmp.close();
-
- // Delete dataholder for replaced original file
- for (unsigned i=0; i<file_channels; i++) {
- delete[] data2beoverwritten[i];
- }
-
- orig->close();
- orig->openRead();
- orig->update();
- audio->msgIdle(false);
- }
-
-//---------------------------------------------------------
-// importAudio
-//---------------------------------------------------------
-
-void MusE::importWave()
- {
- Track* track = arranger->curTrack();
- if (track == 0 || track->type() != Track::WAVE) {
- QMessageBox::critical(this, QString("MusE"),
- tr("to import an audio file you have first to select"
- "a wave track"));
- return;
- }
- //QString fn = getOpenFileName(lastWavePath, audioFilePattern, this,
- QString fn = getOpenFileName(lastWavePath, audio_file_pattern, this,
- tr("Import Wave File"), 0);
- if (!fn.isEmpty()) {
- lastWavePath = fn;
- importWaveToTrack(fn);
- }
- }
-
-//---------------------------------------------------------
-// importWaveToTrack
-//---------------------------------------------------------
-
-bool MusE::importWaveToTrack(QString& name, unsigned tick, Track* track)
- {
- if (track==NULL)
- track = (WaveTrack*)(arranger->curTrack());
-
- SndFile* f = getWave(name, true);
-
- if (f == 0) {
- printf("import audio file failed\n");
- return true;
- }
- int samples = f->samples();
- if ((unsigned)sampleRate !=f->samplerate()) {
- if(QMessageBox::question(this, tr("Import Wavefile"),
- tr("This wave file has a samplerate of %1,\n"
- "as opposed to current setting %2.\n"
- "Do you still want to import it?").arg(f->samplerate()).arg(sampleRate),
- tr("&Yes"), tr("&No"),
- QString::null, 0, 1 ))
- {
- //printf("why won't muse let me delete the file object? %d\n", f->getRefCount());
- if (f->getRefCount() == 0)
- delete f;
- return true;
- }
- }
- track->setChannels(f->channels());
-
- WavePart* part = new WavePart((WaveTrack *)track);
- if (tick)
- part->setTick(tick);
- else
- part->setTick(song->cpos());
- part->setLenFrame(samples);
-
- Event event(Wave);
- SndFileR sf(f);
- event.setSndFile(sf);
- event.setSpos(0);
- event.setLenFrame(samples);
- part->addEvent(event);
-
- part->setName(QFileInfo(name).completeBaseName());
- audio->msgAddPart(part);
- unsigned endTick = part->tick() + part->lenTick();
- if (song->len() < endTick)
- song->setLen(endTick);
- return false;
- }
-#if 0
-//---------------------------------------------------------
-// Clip
-//---------------------------------------------------------
-
-ClipBase::ClipBase(const SndFileR& file, int start, int l)
- : f(file)
- {
- refCount = 0;
- for (int i = 1; true; ++i) {
- _name.sprintf("%s.%d", f.basename().toLatin1().constData(), i);
- ciClip ic = waveClips->begin();
- for (; ic != waveClips->end(); ++ic) {
- if ((*ic)->name() == _name)
- break;
- }
- if (ic == waveClips->end())
- break;
- // try another name
- }
- _spos = start;
- len = l;
- deleted = false;
- lrefs = 0;
- waveClips->add(this);
- }
-
-//---------------------------------------------------------
-// read
-//---------------------------------------------------------
-
-void ClipBase::read(unsigned srcOffset, float** buffer, int channel, unsigned n)
- {
- if (f.isNull())
- return;
- f.seek(srcOffset + _spos, 0);
- f.read(channel, buffer, n);
- }
-
-ClipBase::~ClipBase()
- {
- waveClips->remove(this);
- }
-
-//---------------------------------------------------------
-// ClipList::write(level, xml)
-//---------------------------------------------------------
-
-void ClipList::write(int level, Xml& xml) const
- {
- for (ciClip i = begin(); i != end(); ++i) {
- ClipBase* clip = *i;
- // only write visible clips
- if (clip->references())
- (*i)->write(level, xml);
- }
- }
-
-//---------------------------------------------------------
-// ClipBase::write(level, xml)
-//---------------------------------------------------------
-
-void ClipBase::write(int level, Xml& xml) const
- {
- xml.tag(level++, "clip");
- QString path = f.dirPath();
-
- //
- // waves in the project dirctory are stored
- // with relative path name, others with absolute path
- //
- if (path == museProject)
- xml.strTag(level, "file", f.name());
- else
- xml.strTag(level, "file", f.path());
-
- xml.strTag(level, "name", _name);
- xml.intTag(level, "tick", _spos);
- xml.intTag(level, "len", len);
- xml.etag(level, "clip");
- }
-
-//---------------------------------------------------------
-// ClipBase::read
-//---------------------------------------------------------
-
-ClipBase* readClip(Xml& xml)
- {
- SndFile* f = 0;
- QString name;
- unsigned spos = 0;
- int len = 0;
-
- for (;;) {
- Xml::Token token = xml.parse();
- const QString& tag = xml.s1();
- switch (token) {
- case Xml::Error:
- case Xml::End:
- return 0;
- case Xml::TagStart:
- if (tag == "file")
- f = getWave(xml.parse1(), false);
- else if (tag == "name")
- name = xml.parse1();
- else if (tag == "tick")
- spos = xml.parseInt();
- else if (tag == "len")
- len = xml.parseInt();
- else
- xml.unknown("Clip");
- break;
- case Xml::TagEnd:
- if (tag == "clip") {
- if (!f)
- printf("clip: file not found\n");
- ClipBase* clip = new ClipBase(f, spos, len);
- clip->setName(name);
- return clip;
- }
- default:
- break;
- }
- }
- }
-
-//---------------------------------------------------------
-// search
-//---------------------------------------------------------
-
-Clip ClipList::search(const QString& name) const
- {
- for (ciClip i = begin(); i != end(); ++i)
- if ((*i)->name() == name)
- return Clip(*i);
- fprintf(stderr, "ClipList: clip <%s> not found\n",
- name.toLatin1().constData());
- return Clip();
- }
-
-//---------------------------------------------------------
-// remove
-//---------------------------------------------------------
-
-void ClipList::remove(ClipBase* clip)
- {
- for (iClip i = begin(); i != end(); ++i) {
- if (*i == clip) {
- erase(i);
- return;
- }
- }
- printf("ClipList:remove: clip not found\n");
- }
-
-//---------------------------------------------------------
-// idx
-//---------------------------------------------------------
-
-int ClipList::idx(const Clip& clip) const
- {
- int n = 0;
- for (ciClip i = begin(); i != end(); ++i, ++n) {
- if (clip == *i)
- return n;
- }
- return -1;
- }
-#endif
-
-//---------------------------------------------------------
-// cmdAddRecordedWave
-//---------------------------------------------------------
-
-//void Song::cmdAddRecordedWave(WaveTrack* track, const Pos& s, const Pos& e)
-void Song::cmdAddRecordedWave(WaveTrack* track, Pos s, Pos e)
- {
- SndFile* f = track->recFile();
- if (f == 0) {
- printf("cmdAddRecordedWave: no snd file for track <%s>\n",
- track->name().toLatin1().constData());
- return;
- }
-
- // Removed by Tim. p3.3.8
- //unsigned startTick = roundDownBar(s.tick());
- //unsigned endTick = roundUpBar(e.tick());
-
- // Added by Tim. p3.3.8
-
- if((audio->loopCount() > 0 && s.tick() > lPos().tick()) || (punchin() && s.tick() < lPos().tick()))
- s.setTick(lPos().tick());
- // If we are looping, just set the end to the right marker, since we don't know how many loops have occurred.
- // (Fixed: Added Audio::loopCount)
- // Otherwise if punchout is on, limit the end to the right marker.
- //if(loop() || (punchout() && e.tick() > rPos().tick()) )
- if((audio->loopCount() > 0) || (punchout() && e.tick() > rPos().tick()) )
- e.setTick(rPos().tick());
- // No part to be created? Delete the rec sound file.
- if(s.tick() >= e.tick())
- {
- QString s = f->path();
- delete f;
- // The function which calls this function already does this immediately after. But do it here anyway.
- track->setRecFile(0);
- remove(s.toLatin1().constData());
- if(debugMsg)
- printf("Song::cmdAddRecordedWave: remove file %s\n", s.toLatin1().constData());
- return;
- }
- // Round the start down using the Arranger part snap raster value.
- unsigned startTick = AL::sigmap.raster1(s.tick(), song->arrangerRaster());
- // Round the end up using the Arranger part snap raster value.
- unsigned endTick = AL::sigmap.raster2(e.tick(), song->arrangerRaster());
-
- f->update();
-
- WavePart* part = new WavePart(track);
- part->setTick(startTick);
- part->setLenTick(endTick - startTick);
- part->setName(track->name());
-
- // create Event
- Event event(Wave);
- SndFileR sf(f);
- event.setSndFile(sf);
- // We are done with the _recFile member. Set to zero. The function which
- // calls this function already does this immediately after. But do it here anyway.
- track->setRecFile(0);
-
- event.setSpos(0);
-
- // Since the part start was snapped down, we must apply the difference so that the
- // wave event tick lines up with when the user actually started recording.
- // Added by Tim. p3.3.8
- event.setTick(s.tick() - startTick);
-
-
- event.setLenFrame(e.frame() - s.frame());
- part->addEvent(event);
-
- song->cmdAddPart(part);
-
- if (song->len() < endTick)
- song->setLen(endTick);
- }
-
-//---------------------------------------------------------
-// cmdChangeWave
-// called from GUI context
-//---------------------------------------------------------
-void Song::cmdChangeWave(QString original, QString tmpfile, unsigned sx, unsigned ex)
- {
- char* original_charstr = new char[original.length() + 1];
- char* tmpfile_charstr = new char[tmpfile.length() + 1];
- strcpy(original_charstr, original.toLatin1().constData());
- strcpy(tmpfile_charstr, tmpfile.toLatin1().constData());
- song->undoOp(UndoOp::ModifyClip, original_charstr, tmpfile_charstr, sx, ex);
- }
-
-//---------------------------------------------------------
-// SndFileR
-//---------------------------------------------------------
-
-SndFileR::SndFileR(SndFile* _sf)
- {
- sf = _sf;
- if (sf)
- (sf->refCount)++;
- }
-
-SndFileR::SndFileR(const SndFileR& ed)
- {
- sf = ed.sf;
- if (sf)
- (sf->refCount)++;
- }
-
-//---------------------------------------------------------
-// operator=
-//---------------------------------------------------------
-
-SndFileR& SndFileR::operator=(const SndFileR& ed)
- {
- if (sf == ed.sf)
- return *this;
- if (sf && --(sf->refCount) == 0) {
- delete sf;
- }
- sf = ed.sf;
- if (sf)
- (sf->refCount)++;
- return *this;
- }
-
-//---------------------------------------------------------
-// ~SndFileR
-//---------------------------------------------------------
-
-SndFileR::~SndFileR()
- {
- if (sf)
- if (--(sf->refCount) == 0) {
- delete sf;
- sf=NULL;
- }
- }