Logo Search packages:      
Sourcecode: rosegarden version File versions  Download package


// -*- c-basic-offset: 4 -*-

    A sequencer and musical notation editor.

    This program is Copyright 2000-2006
        Guillaume Laurent   <glaurent@telegraph-road.org>,
        Chris Cannam        <cannam@all-day-breakfast.com>,
        Richard Bown        <bownie@bownie.com>

    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.


#include "Instrument.h"
#include "RingBuffer.h"
#include "AudioFile.h"
#include "AudioCache.h"

#include <string>
#include <map>

namespace Rosegarden

class RingBufferPool;

class PlayableAudioFile
    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

    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 Rosegarden::RealTime &time) 
        { m_fadeInTime = time; }

    RealTime getFadeOutTime() const { return m_fadeOutTime; }
    void setFadeOutTime(const Rosegarden::RealTime &time) 
        { m_fadeOutTime = time; }

    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;

    bool                  m_autoFade;
    Rosegarden::RealTime  m_fadeInTime;
    Rosegarden::RealTime  m_fadeOutTime;

    PlayableAudioFile(const PlayableAudioFile &pAF); // not provided

// A wrapper class for writing out a recording file.  We assume the
// data is provided by a process thread and the writes are requested
// by a disk thread.
class RecordableAudioFile
    typedef float sample_t;

    typedef enum
    } RecordStatus;

    RecordableAudioFile(AudioFile *audioFile, // should be already open for writing
                  size_t bufferSize);

    void setStatus(const RecordStatus &status) { m_status = status; }
    RecordStatus getStatus() const { return m_status; }

    size_t buffer(const sample_t *data, int channel, size_t frames);
    void write();

    AudioFile            *m_audioFile;
    RecordStatus          m_status;

    std::vector<RingBuffer<sample_t> *> m_ringBuffers; // one per channel



Generated by  Doxygen 1.6.0   Back to index