diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 18:37:05 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 18:37:05 +0000 |
commit | 145364a8af6a1fec06556221e66d4b724a62fc9a (patch) | |
tree | 53bd71a544008c518034f208d64c932dc2883f50 /src/sound/PeakFileManager.cpp | |
download | rosegarden-145364a8af6a1fec06556221e66d4b724a62fc9a.tar.gz rosegarden-145364a8af6a1fec06556221e66d4b724a62fc9a.zip |
Added old abandoned KDE3 version of the RoseGarden MIDI tool
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/rosegarden@1097595 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/sound/PeakFileManager.cpp')
-rw-r--r-- | src/sound/PeakFileManager.cpp | 327 |
1 files changed, 327 insertions, 0 deletions
diff --git a/src/sound/PeakFileManager.cpp b/src/sound/PeakFileManager.cpp new file mode 100644 index 0000000..10293e6 --- /dev/null +++ b/src/sound/PeakFileManager.cpp @@ -0,0 +1,327 @@ +// -*- c-basic-offset: 4 -*- + +/* + Rosegarden + A sequencer and musical notation editor. + + This program is Copyright 2000-2008 + Guillaume Laurent <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral right of the authors to claim authorship of this work + has been asserted. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +// Accepts a file handle positioned somewhere in sample data (could +// be at the start) along with the necessary meta information for +// decoding (channels, bits per sample) and turns the sample data +// into peak data and generates a BWF format peak chunk file. This +// file can exist by itself (in the case this is being generated +// by a WAV) or be accomodated inside a BWF format file. +// +// + +#include <string> +#include <vector> + +#include <qobject.h> + +#include "PeakFileManager.h" +#include "AudioFile.h" +#include "RealTime.h" +#include "PeakFile.h" + +namespace Rosegarden +{ + + +PeakFileManager::PeakFileManager(): + m_updatePercentage(0), + m_currentPeakFile(0) +{} + +PeakFileManager::~PeakFileManager() +{} + +// Inserts PeakFile based on AudioFile if it doesn't already exist +bool +PeakFileManager::insertAudioFile(AudioFile *audioFile) +{ + std::vector<PeakFile*>::iterator it; + + for (it = m_peakFiles.begin(); it != m_peakFiles.end(); it++) { + if ((*it)->getAudioFile()->getId() == audioFile->getId()) + return false; + } + + /* + std::cout << "PeakFileManager::insertAudioFile - creating peak file " + << m_peakFiles.size() + 1 + << " for \"" << audioFile->getFilename() + << "\"" << std::endl; + */ + + // Insert + m_peakFiles.push_back(new PeakFile(audioFile)); + + return true; +} + +// Removes peak file from PeakFileManager - doesn't affect audioFile +// +bool +PeakFileManager::removeAudioFile(AudioFile *audioFile) +{ + std::vector<PeakFile*>::iterator it; + + for (it = m_peakFiles.begin(); it != m_peakFiles.end(); it++) { + if ((*it)->getAudioFile()->getId() == audioFile->getId()) { + if (m_currentPeakFile == *it) + m_currentPeakFile = 0; + delete *it; + m_peakFiles.erase(it); + return true; + } + } + + return false; +} + +// Auto-insert PeakFile into manager if it doesn't already exist +// +PeakFile* +PeakFileManager::getPeakFile(AudioFile *audioFile) +{ + std::vector<PeakFile*>::iterator it; + PeakFile *ptr = 0; + + while (ptr == 0) { + for (it = m_peakFiles.begin(); it != m_peakFiles.end(); it++) + if ((*it)->getAudioFile()->getId() == audioFile->getId()) + ptr = *it; + + // If nothing is found then insert and retry + // + if (ptr == 0) { + // Insert - if we fail we return as empty + // + if (insertAudioFile(audioFile) == false) + return 0; + } + } + + return ptr; +} + + +// Does a given AudioFile have a valid peak file or peak chunk? +// +bool +PeakFileManager::hasValidPeaks(AudioFile *audioFile) +{ + if (audioFile->getType() == WAV) { + // Check external peak file + PeakFile *peakFile = getPeakFile(audioFile); + + if (peakFile == 0) { +#ifdef DEBUG_PEAKFILEMANAGER + std::cerr << "PeakFileManager::hasValidPeaks - no peak file found" + << std::endl; +#endif + + return false; + } + // If it doesn't open and parse correctly + if (peakFile->open() == false) + return false; + + // or if the data is old or invalid + if (peakFile->isValid() == false) + return false; + + } else if (audioFile->getType() == BWF) { + // check internal peak chunk + } else { +#ifdef DEBUG_PEAKFILEMANAGER + std::cout << "PeakFileManager::hasValidPeaks - unsupported file type" + << std::endl; +#endif + + return false; + } + + return true; + +} + +// Generate the peak file. Checks to see if peak file exists +// already and if so if it's up to date. If it isn't then we +// regenerate. +// +void +PeakFileManager::generatePeaks(AudioFile *audioFile, + unsigned short updatePercentage) +{ +#ifdef DEBUG_PEAKFILEMANAGER + std::cout << "PeakFileManager::generatePeaks - generating peaks for \"" + << audioFile->getFilename() << "\"" << std::endl; +#endif + + if (audioFile->getType() == WAV) { + m_currentPeakFile = getPeakFile(audioFile); + + QObject::connect(m_currentPeakFile, SIGNAL(setProgress(int)), + this, SIGNAL(setProgress(int))); + + // Just write out a peak file + // + if (m_currentPeakFile->write(updatePercentage) == false) { + std::cerr << "Can't write peak file for " << audioFile->getFilename() << " - no preview generated" << std::endl; + throw BadPeakFileException + (audioFile->getFilename(), __FILE__, __LINE__); + } + + // The m_currentPeakFile might have been cancelled (see stopPreview()) + // + if (m_currentPeakFile) { + // close writes out important things + m_currentPeakFile->close(); + m_currentPeakFile->disconnect(); + } + } else if (audioFile->getType() == BWF) { + // write the file out and incorporate the peak chunk + } else { +#ifdef DEBUG_PEAKFILEMANAGER + std::cerr << "PeakFileManager::generatePeaks - unsupported file type" + << std::endl; +#endif + + return ; + } + + m_currentPeakFile = 0; + +} + +std::vector<float> +PeakFileManager::getPreview(AudioFile *audioFile, + const RealTime &startTime, + const RealTime &endTime, + int width, + bool showMinima) +{ + std::vector<float> rV; + + // If we've got no channels then the audio file hasn't + // completed (recording) - so don't generate a preview + // + if (audioFile->getChannels() == 0) + return rV; + + if (audioFile->getType() == WAV) { + PeakFile *peakFile = getPeakFile(audioFile); + + // just write out a peak file + try { + peakFile->open(); + rV = peakFile->getPreview(startTime, + endTime, + width, + showMinima); + } catch (SoundFile::BadSoundFileException e) { +#ifdef DEBUG_PEAKFILEMANAGER + std::cout << "PeakFileManager::getPreview " + << "\"" << e << "\"" << std::endl; +#else + + ; +#endif + + throw BadPeakFileException(e); + } + } else if (audioFile->getType() == BWF) { + // write the file out and incorporate the peak chunk + } +#ifdef DEBUG_PEAKFILEMANAGER + else { + std::cerr << "PeakFileManager::getPreview - unsupported file type" + << std::endl; + } +#endif + + return rV; +} + +void +PeakFileManager::clear() +{ + std::vector<PeakFile*>::iterator it; + + for (it = m_peakFiles.begin(); it != m_peakFiles.end(); it++) + delete (*it); + + m_peakFiles.erase(m_peakFiles.begin(), m_peakFiles.end()); + + m_currentPeakFile = 0; +} + + +std::vector<SplitPointPair> +PeakFileManager::getSplitPoints(AudioFile *audioFile, + const RealTime &startTime, + const RealTime &endTime, + int threshold, + const RealTime &minTime) +{ + PeakFile *peakFile = getPeakFile(audioFile); + + if (peakFile == 0) + return std::vector<SplitPointPair>(); + + return peakFile->getSplitPoints(startTime, + endTime, + threshold, + minTime); + +} + +void +PeakFileManager::stopPreview() +{ + if (m_currentPeakFile) { + // Stop processing + // + QString fileName = QString(m_currentPeakFile->getFilename().data()); + m_currentPeakFile->setProcessingPeaks(false); + m_currentPeakFile->disconnect(); + + QFile file(fileName); + bool removed = file.remove(); + +#ifdef DEBUG_PEAKFILEMANAGER + + if (removed) { + std::cout << "PeakFileManager::stopPreview() - removed preview" + << std::endl; + } +#endif + //delete m_currentPeakFile; + m_currentPeakFile = 0; + } +} + + + + +} + + +#include "PeakFileManager.moc" |