annotate audio/ClipMixer.h @ 588:d122d3595a32

Store aggregate models in the document and release them when they are invalidated (because their components have been released). They're no longer leaked, but we still don't save them in the session file.
author Chris Cannam
date Mon, 27 Feb 2017 16:26:37 +0000
parents 56acd9368532
children b23bebfdfaba
rev   line source
Chris@305 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@305 2
Chris@305 3 /*
Chris@305 4 Sonic Visualiser
Chris@305 5 An audio file viewer and annotation editor.
Chris@305 6 Centre for Digital Music, Queen Mary, University of London.
Chris@305 7 This file copyright 2006 Chris Cannam, 2006-2014 QMUL.
Chris@305 8
Chris@305 9 This program is free software; you can redistribute it and/or
Chris@305 10 modify it under the terms of the GNU General Public License as
Chris@305 11 published by the Free Software Foundation; either version 2 of the
Chris@305 12 License, or (at your option) any later version. See the file
Chris@305 13 COPYING included with this distribution for more information.
Chris@305 14 */
Chris@305 15
Chris@312 16 #ifndef CLIP_MIXER_H
Chris@312 17 #define CLIP_MIXER_H
Chris@305 18
Chris@305 19 #include <QString>
Chris@305 20 #include <vector>
Chris@305 21
Chris@436 22 #include "base/BaseTypes.h"
Chris@436 23
Chris@305 24 /**
Chris@305 25 * Mix in synthetic notes produced by resampling a prerecorded
Chris@312 26 * clip. (i.e. this is an implementation of a digital sampler in the
Chris@312 27 * musician's sense.) This can mix any number of notes of arbitrary
Chris@312 28 * frequency, so long as they all use the same sample clip.
Chris@305 29 */
Chris@305 30
Chris@305 31 class ClipMixer
Chris@305 32 {
Chris@305 33 public:
Chris@436 34 ClipMixer(int channels, sv_samplerate_t sampleRate, sv_frame_t blockSize);
Chris@305 35 ~ClipMixer();
Chris@305 36
Chris@308 37 void setChannelCount(int channels);
Chris@312 38
Chris@312 39 /**
Chris@312 40 * Load a sample clip from a wav file. This can only happen once:
Chris@349 41 * construct a new ClipMixer if you want a different clip. The
Chris@349 42 * clip was recorded at a pitch with fundamental frequency clipF0,
Chris@349 43 * and should be scaled by level (in the range 0-1) when playing
Chris@349 44 * back.
Chris@312 45 */
Chris@436 46 bool loadClipData(QString clipFilePath, double clipF0, double level);
Chris@305 47
Chris@308 48 void reset(); // discarding any playing notes
Chris@308 49
Chris@305 50 struct NoteStart {
Chris@436 51 sv_frame_t frameOffset; // within current processing block
Chris@305 52 float frequency; // Hz
Chris@305 53 float level; // volume in range (0,1]
Chris@305 54 float pan; // range [-1,1]
Chris@305 55 };
Chris@305 56
Chris@305 57 struct NoteEnd {
Chris@436 58 sv_frame_t frameOffset; // in current processing block
Chris@308 59 float frequency; // matching note start
Chris@305 60 };
Chris@305 61
Chris@305 62 void mix(float **toBuffers,
Chris@308 63 float gain,
Chris@305 64 std::vector<NoteStart> newNotes,
Chris@305 65 std::vector<NoteEnd> endingNotes);
Chris@305 66
Chris@305 67 private:
Chris@305 68 int m_channels;
Chris@436 69 sv_samplerate_t m_sampleRate;
Chris@436 70 sv_frame_t m_blockSize;
Chris@305 71
Chris@305 72 QString m_clipPath;
Chris@305 73
Chris@305 74 float *m_clipData;
Chris@436 75 sv_frame_t m_clipLength;
Chris@436 76 double m_clipF0;
Chris@436 77 sv_samplerate_t m_clipRate;
Chris@310 78
Chris@310 79 std::vector<NoteStart> m_playing;
Chris@310 80
Chris@436 81 double getResampleRatioFor(double frequency);
Chris@436 82 sv_frame_t getResampledClipDuration(double frequency);
Chris@310 83
Chris@310 84 void mixNote(float **toBuffers,
Chris@310 85 float *levels,
Chris@310 86 float frequency,
Chris@436 87 sv_frame_t sourceOffset, // within resampled note
Chris@436 88 sv_frame_t targetOffset, // within target buffer
Chris@436 89 sv_frame_t sampleCount,
matthiasm@320 90 bool isEnd);
Chris@305 91 };
Chris@305 92
Chris@305 93
Chris@305 94 #endif