To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.
root / CollidoscopeApp / include / BufferToWaveRecorderNode.h @ 5:75b744078d66
History | View | Annotate | Download (6.43 KB)
| 1 | 5:75b744078d66 | f | /*
|
|---|---|---|---|
| 2 | |||
| 3 | Copyright (C) 2016 Queen Mary University of London
|
||
| 4 | Author: Fiore Martin
|
||
| 5 | |||
| 6 | This file is part of Collidoscope.
|
||
| 7 | |||
| 8 | Collidoscope is free software: you can redistribute it and/or modify
|
||
| 9 | it under the terms of the GNU General Public License as published by
|
||
| 10 | the Free Software Foundation, either version 3 of the License, or
|
||
| 11 | (at your option) any later version.
|
||
| 12 | |||
| 13 | This program is distributed in the hope that it will be useful,
|
||
| 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
| 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
| 16 | GNU General Public License for more details.
|
||
| 17 | |||
| 18 | You should have received a copy of the GNU General Public License
|
||
| 19 | along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
| 20 | |||
| 21 | This file incorporates work covered by the following copyright and permission notice:
|
||
| 22 | |||
| 23 | Copyright (c) 2014, The Cinder Project
|
||
| 24 | |||
| 25 | This code is intended to be used with the Cinder C++ library, http://libcinder.org
|
||
| 26 | |||
| 27 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that
|
||
| 28 | the following conditions are met:
|
||
| 29 | |||
| 30 | * Redistributions of source code must retain the above copyright notice, this list of conditions and
|
||
| 31 | the following disclaimer.
|
||
| 32 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
|
||
| 33 | the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||
| 34 | |||
| 35 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||
| 36 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||
| 37 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||
| 38 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||
| 39 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||
| 40 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||
| 41 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||
| 42 | POSSIBILITY OF SUCH DAMAGE.
|
||
| 43 | |||
| 44 | */
|
||
| 45 | |||
| 46 | 0:02467299402e | f | #pragma once
|
| 47 | |||
| 48 | #include "cinder/Cinder.h" |
||
| 49 | #include "cinder/audio/Node.h" |
||
| 50 | #include "cinder/audio/SampleRecorderNode.h" |
||
| 51 | #include "cinder/audio/dsp/RingBuffer.h" |
||
| 52 | #include "cinder/Filesystem.h" |
||
| 53 | |||
| 54 | #include "Messages.h" |
||
| 55 | |||
| 56 | 5:75b744078d66 | f | typedef std::shared_ptr<class BufferToWaveRecorderNode> BufferToWaveRecorderNodeRef;
|
| 57 | 0:02467299402e | f | |
| 58 | typedef ci::audio::dsp::RingBufferT<RecordWaveMsg> RecordWaveMsgRingBuffer;
|
||
| 59 | |||
| 60 | 2:dd889fff8423 | f | /**
|
| 61 | * A \a Node in the audio graph of the Cinder audio library that records input in a buffer.
|
||
| 62 | *
|
||
| 63 | * This class is similar to \a cinder::audio::BufferRecorderNode (it's a derivative work of this class indeed) but it has an additional feature.
|
||
| 64 | * When recording it uses the audio input samples to compute the size values of the visual chunks.
|
||
| 65 | * The chunks values are stored in a ring buffer and fetched by the graphic thread to paint the wave as it gets recorded.
|
||
| 66 | *
|
||
| 67 | */
|
||
| 68 | 0:02467299402e | f | class BufferToWaveRecorderNode : public ci::audio::SampleRecorderNode {
|
| 69 | public:
|
||
| 70 | |||
| 71 | static const float kRampTime; |
||
| 72 | |||
| 73 | //! Constructor. numChunks is the total number of chunks this biffer has to be borken down in.
|
||
| 74 | //! numSeconds lenght of the buffer in seconds
|
||
| 75 | BufferToWaveRecorderNode( std::size_t numChunks, double numSeconds );
|
||
| 76 | |||
| 77 | //! Starts recording. Resets the write position to zero (call disable() to pause recording).
|
||
| 78 | void start();
|
||
| 79 | //! Stops recording. Same as calling disable().
|
||
| 80 | void stop();
|
||
| 81 | |||
| 82 | //! \brief Sets the length of the recording buffer in frames.
|
||
| 83 | //!
|
||
| 84 | //! If the write position is non-zero, the old contents will be preserved (by copying it to the newly allocated Buffer).
|
||
| 85 | //! If \a shrinkToFit is set to `true`, the internal Buffer will be down-sized if necessary, otherwise it will only re-allocate when growing while changing its dimensions to match \a numFrames (default shrinkToFit = false).
|
||
| 86 | void setNumFrames(size_t numFrames, bool shrinkToFit = false); |
||
| 87 | //! Sets the length of the recording buffer in seconds. \see setNumFrames
|
||
| 88 | void setNumSeconds(double numSeconds, bool shrinkToFit = false); |
||
| 89 | |||
| 90 | //! Returns the length of the recording buffer in frames.
|
||
| 91 | 5:75b744078d66 | f | size_t getNumFrames() const { return mRecorderBuffer.getNumFrames(); } |
| 92 | 0:02467299402e | f | //! Returns the length of the recording buffer in seconds.
|
| 93 | 5:75b744078d66 | f | double getNumSeconds() const; |
| 94 | 0:02467299402e | f | |
| 95 | //! \brief Returns a copy of the recored samples, up to the current write position.
|
||
| 96 | //!
|
||
| 97 | //! This method is non locking, and as such any resizing calls must be performed on the same thread or be otherwise synchronized.
|
||
| 98 | 5:75b744078d66 | f | ci::audio::BufferRef getRecordedCopy() const;
|
| 99 | 0:02467299402e | f | |
| 100 | //! \brief Writes the currently recorded samples to a file at \a filePath
|
||
| 101 | //!
|
||
| 102 | //! The encoding format is derived from \a filePath's extension and \a sampleType (default = SampleType::INT_16).
|
||
| 103 | //! \note throws AudioFileExc if the write request cannot be completed.
|
||
| 104 | void writeToFile(const ci::fs::path &filePath, ci::audio::SampleType sampleType = ci::audio::SampleType::INT_16); |
||
| 105 | |||
| 106 | //! Returns the frame of the last buffer overrun or 0 if none since the last time this method was called. When this happens, it means the recorded buffer probably has skipped some frames.
|
||
| 107 | uint64_t getLastOverrun(); |
||
| 108 | |||
| 109 | 2:dd889fff8423 | f | //! returns a reference to the ring buffer when the size values of the chunks is stored, when a new wave is recorder
|
| 110 | 0:02467299402e | f | RecordWaveMsgRingBuffer& getRingBuffer() { return mRingBuffer; }
|
| 111 | |||
| 112 | 2:dd889fff8423 | f | //!returns a pointer to the buffer where the audio is recorder. This is used by the PGranular to create the granular synthesis
|
| 113 | 0:02467299402e | f | ci::audio::Buffer* getRecorderBuffer() { return &mRecorderBuffer; }
|
| 114 | |||
| 115 | |||
| 116 | protected:
|
||
| 117 | 5:75b744078d66 | f | void initialize() override;
|
| 118 | void process(ci::audio::Buffer *buffer) override;
|
||
| 119 | 0:02467299402e | f | |
| 120 | void initBuffers(size_t numFrames);
|
||
| 121 | |||
| 122 | static const float kMinAudioVal; |
||
| 123 | static const float kMaxAudioVal; |
||
| 124 | |||
| 125 | 5:75b744078d66 | f | ci::audio::BufferDynamic mRecorderBuffer; |
| 126 | ci::audio::BufferDynamicRef mCopiedBuffer; |
||
| 127 | std::atomic<uint64_t> mLastOverrun; |
||
| 128 | 0:02467299402e | f | |
| 129 | RecordWaveMsgRingBuffer mRingBuffer; |
||
| 130 | |||
| 131 | const std::size_t mNumChunks;
|
||
| 132 | const double mNumSeconds; |
||
| 133 | std::size_t mNumSamplesPerChunk; |
||
| 134 | std::atomic<std::size_t> mChunkIndex; |
||
| 135 | |||
| 136 | size_t mChunkSampleCounter; |
||
| 137 | float mChunkMaxAudioVal;
|
||
| 138 | float mChunkMinAudioVal;
|
||
| 139 | |||
| 140 | float mEnvRamp;
|
||
| 141 | float mEnvRampRate;
|
||
| 142 | size_t mEnvRampLen; |
||
| 143 | size_t mEnvDecayStart; |
||
| 144 | |||
| 145 | }; |