summaryrefslogtreecommitdiffstats
path: root/src/sound/PlayableAudioFile.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/sound/PlayableAudioFile.h')
-rw-r--r--src/sound/PlayableAudioFile.h219
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 &currentTime);
+
+ 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