Mercurial > hg > svapp
view 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 |
line wrap: on
line source
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ /* Sonic Visualiser An audio file viewer and annotation editor. Centre for Digital Music, Queen Mary, University of London. This file copyright 2006 Chris Cannam, 2006-2014 QMUL. 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 CLIP_MIXER_H #define CLIP_MIXER_H #include <QString> #include <vector> #include "base/BaseTypes.h" /** * Mix in synthetic notes produced by resampling a prerecorded * clip. (i.e. this is an implementation of a digital sampler in the * musician's sense.) This can mix any number of notes of arbitrary * frequency, so long as they all use the same sample clip. */ class ClipMixer { public: ClipMixer(int channels, sv_samplerate_t sampleRate, sv_frame_t blockSize); ~ClipMixer(); void setChannelCount(int channels); /** * Load a sample clip from a wav file. This can only happen once: * construct a new ClipMixer if you want a different clip. The * clip was recorded at a pitch with fundamental frequency clipF0, * and should be scaled by level (in the range 0-1) when playing * back. */ bool loadClipData(QString clipFilePath, double clipF0, double level); void reset(); // discarding any playing notes struct NoteStart { sv_frame_t frameOffset; // within current processing block float frequency; // Hz float level; // volume in range (0,1] float pan; // range [-1,1] }; struct NoteEnd { sv_frame_t frameOffset; // in current processing block float frequency; // matching note start }; void mix(float **toBuffers, float gain, std::vector<NoteStart> newNotes, std::vector<NoteEnd> endingNotes); private: int m_channels; sv_samplerate_t m_sampleRate; sv_frame_t m_blockSize; QString m_clipPath; float *m_clipData; sv_frame_t m_clipLength; double m_clipF0; sv_samplerate_t m_clipRate; std::vector<NoteStart> m_playing; double getResampleRatioFor(double frequency); sv_frame_t getResampledClipDuration(double frequency); void mixNote(float **toBuffers, float *levels, float frequency, sv_frame_t sourceOffset, // within resampled note sv_frame_t targetOffset, // within target buffer sv_frame_t sampleCount, bool isEnd); }; #endif