diff options
Diffstat (limited to 'attic/muse2-oom/muse2/muse/wave.cpp')
-rw-r--r-- | attic/muse2-oom/muse2/muse/wave.cpp | 1176 |
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; - } - } |