diff options
Diffstat (limited to 'src/sound/PlayableAudioFile.h')
-rw-r--r-- | src/sound/PlayableAudioFile.h | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/src/sound/PlayableAudioFile.h b/src/sound/PlayableAudioFile.h new file mode 100644 index 0000000..648ad4c --- /dev/null +++ b/src/sound/PlayableAudioFile.h @@ -0,0 +1,219 @@ +// -*- 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. +*/ + +#ifndef _PLAYABLE_AUDIO_FILE_H_ +#define _PLAYABLE_AUDIO_FILE_H_ + +#include "Instrument.h" +#include "RingBuffer.h" +#include "AudioFile.h" +#include "AudioCache.h" + +#include <string> +#include <map> + +namespace Rosegarden +{ + +class RingBufferPool; + + +class PlayableAudioFile +{ +public: + typedef float sample_t; + + PlayableAudioFile(InstrumentId instrumentId, + AudioFile *audioFile, + const RealTime &startTime, + const RealTime &startIndex, + const RealTime &duration, + size_t bufferSize = 4096, + size_t smallFileSize = 131072, + int targetChannels = -1, // default same as file + int targetSampleRate = -1); // default same as file + ~PlayableAudioFile(); + + static void setRingBufferPoolSizes(size_t n, size_t nframes); + + void setStartTime(const RealTime &time) { m_startTime = time; } + RealTime getStartTime() const { return m_startTime; } + + void setDuration(const RealTime &time) { m_duration = time; } + RealTime getDuration() const { return m_duration; } + RealTime getEndTime() const { return m_startTime + m_duration; } + + void setStartIndex(const RealTime &time) { m_startIndex = time; } + RealTime getStartIndex() const { return m_startIndex; } + + bool isSmallFile() const { return m_isSmallFile; } + + // Get audio file for interrogation + // + AudioFile* getAudioFile() const { return m_audioFile; } + + // Get instrument ID - we need to be able to map back + // at the GUI. + // + InstrumentId getInstrument() const { return m_instrumentId; } + + // Return the number of frames currently buffered. The next call + // to getSamples on any channel is guaranteed to return at least + // this many samples. + // + size_t getSampleFramesAvailable(); + + // Read samples from the given channel on the file and add them + // into the destination. + // + // If insufficient frames are available, this will leave the + // excess samples unchanged. + // + // Returns the actual number of samples written. + // + // If offset is non-zero, the samples will be written starting at + // offset frames from the start of the target block. + // + size_t addSamples(std::vector<sample_t *> &target, + size_t channels, size_t nframes, size_t offset = 0); + + unsigned int getSourceChannels(); + unsigned int getTargetChannels(); + unsigned int getSourceSampleRate(); + unsigned int getTargetSampleRate(); + + unsigned int getBitsPerSample(); + unsigned int getBytesPerFrame(); + + // Clear out and refill the ring buffer for immediate + // (asynchronous) play. + // + void fillBuffers(); + + // Clear out and refill the ring buffer (in preparation for + // playback) according to the proposed play time. + // + // This call and updateBuffers are not thread-safe (for + // performance reasons). They should be called for all files + // sequentially within a single thread. + // + bool fillBuffers(const RealTime ¤tTime); + + void clearBuffers(); + + // Update the buffer during playback. + // + // This call and fillBuffers are not thread-safe (for performance + // reasons). They should be called for all files sequentially + // within a single thread. + // + bool updateBuffers(); + + // Has fillBuffers been called and completed yet? + // + bool isBuffered() const { return m_currentScanPoint > m_startIndex; } + + // Has all the data in this file now been read into the buffers? + // + bool isFullyBuffered() const { return m_isSmallFile || m_fileEnded; } + + // Stop playing this file. + // + void cancel() { m_fileEnded = true; } + + // Segment id that allows us to crosscheck against playing audio + // segments. + // + int getRuntimeSegmentId() const { return m_runtimeSegmentId; } + void setRuntimeSegmentId(int id) { m_runtimeSegmentId = id; } + + // Auto fading of a playable audio file + // + bool isAutoFading() const { return m_autoFade; } + void setAutoFade(bool value) { m_autoFade = value; } + + RealTime getFadeInTime() const { return m_fadeInTime; } + void setFadeInTime(const RealTime &time) + { m_fadeInTime = time; } + + RealTime getFadeOutTime() const { return m_fadeOutTime; } + void setFadeOutTime(const RealTime &time) + { m_fadeOutTime = time; } + + +protected: + void initialise(size_t bufferSize, size_t smallFileSize); + void checkSmallFileCache(size_t smallFileSize); + bool scanTo(const RealTime &time); + void returnRingBuffers(); + + RealTime m_startTime; + RealTime m_startIndex; + RealTime m_duration; + + // Performance file handle - must open non-blocking to + // allow other potential PlayableAudioFiles access to + // the same file. + // + std::ifstream *m_file; + + // AudioFile handle + // + AudioFile *m_audioFile; + + // Originating Instrument Id + // + InstrumentId m_instrumentId; + + int m_targetChannels; + int m_targetSampleRate; + + bool m_fileEnded; + bool m_firstRead; + static size_t m_xfadeFrames; + int m_runtimeSegmentId; + + static AudioCache m_smallFileCache; + bool m_isSmallFile; + + static std::vector<sample_t *> m_workBuffers; + static size_t m_workBufferSize; + + static char *m_rawFileBuffer; + static size_t m_rawFileBufferSize; + + RingBuffer<sample_t> **m_ringBuffers; + static RingBufferPool *m_ringBufferPool; + + RealTime m_currentScanPoint; + size_t m_smallFileScanFrame; + + bool m_autoFade; + RealTime m_fadeInTime; + RealTime m_fadeOutTime; + +private: + PlayableAudioFile(const PlayableAudioFile &pAF); // not provided +}; + +} + +#endif |