1 /* ----------------------------------------------------------------------------- 2 * 3 * Giada - Your Hardcore Loopmachine 4 * 5 * ----------------------------------------------------------------------------- 6 * 7 * Copyright (C) 2010-2020 Giovanni A. Zuliani | Monocasual 8 * 9 * This file is part of Giada - Your Hardcore Loopmachine. 10 * 11 * Giada - Your Hardcore Loopmachine is free software: you can 12 * redistribute it and/or modify it under the terms of the GNU General 13 * Public License as published by the Free Software Foundation, either 14 * version 3 of the License, or (at your option) any later version. 15 * 16 * Giada - Your Hardcore Loopmachine is distributed in the hope that it 17 * will be useful, but WITHOUT ANY WARRANTY; without even the implied 18 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 * See the GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with Giada - Your Hardcore Loopmachine. If not, see 23 * <http://www.gnu.org/licenses/>. 24 * 25 * -------------------------------------------------------------------------- */ 26 27 28 #ifndef G_MIXER_H 29 #define G_MIXER_H 30 31 32 #include <atomic> 33 #include <functional> 34 #include <vector> 35 #include "deps/rtaudio/RtAudio.h" 36 #include "core/ringBuffer.h" 37 #include "core/recorder.h" 38 #include "core/types.h" 39 #include "core/queue.h" 40 #include "core/midiEvent.h" 41 42 43 namespace giada { 44 namespace m 45 { 46 struct Action; 47 class Channel; 48 class AudioBuffer; 49 50 namespace mixer 51 { 52 enum class EventType 53 { 54 KEY_PRESS, 55 KEY_RELEASE, 56 KEY_KILL, 57 SEQUENCER_FIRST_BEAT, // 3 58 SEQUENCER_BAR, // 4 59 SEQUENCER_START, // 5 60 SEQUENCER_STOP, // 6 61 SEQUENCER_REWIND, // 7 62 SEQUENCER_REWIND_REQ, // 8 63 MIDI, 64 ACTION, 65 CHANNEL_TOGGLE_READ_ACTIONS, 66 CHANNEL_KILL_READ_ACTIONS, 67 CHANNEL_TOGGLE_ARM, 68 CHANNEL_MUTE, 69 CHANNEL_SOLO, 70 CHANNEL_VOLUME, 71 CHANNEL_PITCH, 72 CHANNEL_PAN 73 }; 74 75 struct Event 76 { 77 EventType type; 78 Frame delta; 79 Action action; 80 }; 81 82 /* EventBuffer 83 Alias for a RingBuffer containing events to be sent to engine. The double size 84 is due to the presence of two distinct Queues for collecting events coming from 85 other threads. See below. */ 86 87 using EventBuffer = RingBuffer<Event, G_MAX_QUEUE_EVENTS * 2>; 88 89 constexpr int MASTER_OUT_CHANNEL_ID = 1; 90 constexpr int MASTER_IN_CHANNEL_ID = 2; 91 constexpr int PREVIEW_CHANNEL_ID = 3; 92 93 extern std::atomic<float> peakOut; // TODO - move to model:: 94 extern std::atomic<float> peakIn; // TODO - move to model:: 95 96 /* Channel Event queues 97 Collect events coming from the UI or MIDI devices to be sent to channels. Our 98 poor's man Queue is a single-producer/single-consumer one, so we need two queues 99 for two writers. TODO - let's add a multi-producer queue sooner or later! */ 100 101 extern Queue<Event, G_MAX_QUEUE_EVENTS> UIevents; 102 extern Queue<Event, G_MAX_QUEUE_EVENTS> MidiEvents; 103 104 void init(Frame framesInSeq, Frame framesInBuffer); 105 106 /* enable, disable 107 Toggles master callback processing. Useful when loading a new patch. Mixer 108 will flush itself to wait for a processing cycle to finish when disable() is 109 called. */ 110 111 void enable(); 112 void disable(); 113 114 /* allocRecBuffer 115 Allocates new memory for the virtual input channel. Call this whenever you 116 shrink or resize the sequencer. */ 117 118 void allocRecBuffer(Frame frames); 119 120 /* clearRecBuffer 121 Clears internal virtual channel. */ 122 123 void clearRecBuffer(); 124 125 /* getRecBuffer 126 Returns a read-only reference to the internal virtual channel. Use this to 127 merge data into channel after an input recording session. */ 128 129 const AudioBuffer& getRecBuffer(); 130 131 void close(); 132 133 /* masterPlay 134 Core method (callback) */ 135 136 int masterPlay(void* outBuf, void* inBuf, unsigned bufferSize, double streamTime, 137 RtAudioStreamStatus status, void* userData); 138 139 /* startInputRec, stopInputRec 140 Starts/stops input recording on frame clock::getCurrentFrame(). */ 141 142 void startInputRec(); 143 void stopInputRec(); 144 145 void setSignalCallback(std::function<void()> f); 146 147 /* pumpEvent 148 Pumps a new mixer::Event into the event vector. Use this function when you want 149 to inject a new event for the **current** block. Push the event in the two 150 queues UIevents and MIDIevents above if the event can be processed in the next 151 block instead. */ 152 153 void pumpEvent(Event e); 154 }}} // giada::m::mixer::; 155 156 157 #endif 158