annotate audioio/ClipMixer.h @ 342:4eccff14b4d8 tonioni

Much fiddling toward getting sessions and individual audio files to load cleanly when they need quite different handling after load
author Chris Cannam
date Wed, 02 Apr 2014 21:25:56 +0100
parents 7105604e9803
children 8d7f39df44ed
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@305 22 /**
Chris@305 23 * Mix in synthetic notes produced by resampling a prerecorded
Chris@312 24 * clip. (i.e. this is an implementation of a digital sampler in the
Chris@312 25 * musician's sense.) This can mix any number of notes of arbitrary
Chris@312 26 * frequency, so long as they all use the same sample clip.
Chris@305 27 */
Chris@305 28
Chris@305 29 class ClipMixer
Chris@305 30 {
Chris@305 31 public:
Chris@305 32 ClipMixer(int channels, int sampleRate, int blockSize);
Chris@305 33 ~ClipMixer();
Chris@305 34
Chris@308 35 void setChannelCount(int channels);
Chris@312 36
Chris@312 37 /**
Chris@312 38 * Load a sample clip from a wav file. This can only happen once:
Chris@312 39 * construct a new ClipMixer if you want a different clip.
Chris@312 40 */
Chris@305 41 bool loadClipData(QString clipFilePath, float clipF0);
Chris@305 42
Chris@308 43 void reset(); // discarding any playing notes
Chris@308 44
Chris@305 45 struct NoteStart {
Chris@310 46 int frameOffset; // within current processing block
Chris@305 47 float frequency; // Hz
Chris@305 48 float level; // volume in range (0,1]
Chris@305 49 float pan; // range [-1,1]
Chris@305 50 };
Chris@305 51
Chris@305 52 struct NoteEnd {
Chris@310 53 int frameOffset; // in current processing block
Chris@308 54 float frequency; // matching note start
Chris@305 55 };
Chris@305 56
Chris@305 57 void mix(float **toBuffers,
Chris@308 58 float gain,
Chris@305 59 std::vector<NoteStart> newNotes,
Chris@305 60 std::vector<NoteEnd> endingNotes);
Chris@305 61
Chris@305 62 private:
Chris@305 63 int m_channels;
Chris@305 64 int m_sampleRate;
Chris@305 65 int m_blockSize;
Chris@305 66
Chris@305 67 QString m_clipPath;
Chris@305 68
Chris@305 69 float *m_clipData;
Chris@305 70 int m_clipLength;
Chris@305 71 float m_clipF0;
Chris@305 72 float m_clipRate;
Chris@310 73
Chris@310 74 std::vector<NoteStart> m_playing;
Chris@310 75
Chris@310 76 float getResampleRatioFor(float frequency);
Chris@310 77 int getResampledClipDuration(float frequency);
Chris@310 78
Chris@310 79 void mixNote(float **toBuffers,
Chris@310 80 float *levels,
Chris@310 81 float frequency,
Chris@310 82 int sourceOffset, // within resampled note
Chris@310 83 int targetOffset, // within target buffer
matthiasm@320 84 int sampleCount,
matthiasm@320 85 bool isEnd);
Chris@305 86 };
Chris@305 87
Chris@305 88
Chris@305 89 #endif