1 /* 2 * Copyright (c) 2009, The MilkyTracker Team. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * - Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * - Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * - Neither the name of the <ORGANIZATION> nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 /* 31 * MasterMixer.h 32 * MilkyPlay 33 * 34 * Created by Peter Barth on 14.12.07. 35 * 36 */ 37 38 #ifndef __MASTERMIXER_H__ 39 #define __MASTERMIXER_H__ 40 41 #include "Mixable.h" 42 43 class MasterMixer 44 { 45 public: 46 enum MasterMixerNotifications 47 { 48 MasterMixerNotificationBufferSizeChanged, 49 MasterMixerNotificationSampleRateChanged 50 }; 51 52 class MasterMixerNotificationListener 53 { 54 public: ~MasterMixerNotificationListener()55 virtual ~MasterMixerNotificationListener() 56 { 57 } 58 59 virtual void masterMixerNotification(MasterMixerNotifications notification) = 0; 60 }; 61 62 MasterMixer(mp_uint32 sampleRate, 63 mp_uint32 bufferSize = 0, 64 mp_uint32 numDevices = 1, 65 class AudioDriverInterface* audioDriver = 0); 66 67 virtual ~MasterMixer(); 68 69 void setMasterMixerNotificationListener(MasterMixerNotificationListener* listener); 70 71 mp_sint32 openAudioDevice(); 72 mp_sint32 closeAudioDevice(); 73 74 mp_sint32 start(); 75 mp_sint32 stop(); 76 mp_sint32 pause(); 77 mp_sint32 resume(); 78 isPlaying()79 bool isPlaying() const { return started; } isPaused()80 bool isPaused() const { return paused; } isInitialized()81 bool isInitialized() const { return initialized; } isActive()82 bool isActive() const { return started && !paused; } 83 84 mp_sint32 setBufferSize(mp_uint32 bufferSize); getBufferSize()85 mp_uint32 getBufferSize() const { return bufferSize; } 86 87 mp_sint32 setSampleRate(mp_uint32 sampleRate); getSampleRate()88 mp_uint32 getSampleRate() const { return sampleRate; } 89 90 bool addDevice(Mixable* device, bool paused = false); 91 bool removeDevice(Mixable* device, bool blocking = true); 92 bool isDeviceRemoved(Mixable* device); 93 94 bool pauseDevice(Mixable* device, bool blocking = true); 95 bool resumeDevice(Mixable* device); 96 bool isDevicePaused(Mixable* device); 97 98 void mixerHandler(mp_sword* buffer); 99 100 // allows to control the loudness of the resulting output stream 101 // by bit-shifting the output *right* (dividing by 2^shift) setSampleShift(mp_sint32 shift)102 void setSampleShift(mp_sint32 shift) { sampleShift = shift; } getSampleShift()103 mp_uint32 getSampleShift() const { return sampleShift; } 104 105 // disable mixing... you don't need to understand this setDisableMixing(bool disableMixing)106 void setDisableMixing(bool disableMixing) { this->disableMixing = disableMixing; } 107 setFilterHook(Mixable * filterHook)108 void setFilterHook(Mixable* filterHook) { this->filterHook = filterHook; } getFilterHook(Mixable * filterHook)109 Mixable* getFilterHook(Mixable* filterHook) const { return filterHook; } 110 111 // some legacy functions used by milkytracker getAudioDriver()112 const class AudioDriverInterface* getAudioDriver() const { return audioDriver; } 113 114 const char* getCurrentAudioDriverName() const; 115 bool setCurrentAudioDriverByName(const char* name); 116 117 const class AudioDriverManager* getAudioDriverManager() const; 118 119 mp_sint32 getCurrentSample(mp_sint32 position, mp_sint32 channel); 120 mp_sint32 getCurrentSamplePeak(mp_sint32 position, mp_sint32 channel); 121 122 private: 123 MasterMixerNotificationListener* listener; 124 mp_uint32 sampleRate; 125 mp_uint32 bufferSize; 126 mp_sint32* buffer; 127 mp_uint32 sampleShift; 128 bool disableMixing; 129 mp_uint32 numDevices; 130 Mixable* filterHook; 131 132 struct DeviceDescriptor 133 { 134 Mixable* mixable; 135 bool markedForRemoval; 136 bool markedForPause; 137 bool paused; 138 DeviceDescriptorDeviceDescriptor139 DeviceDescriptor() : 140 mixable(0), 141 markedForRemoval(false), 142 markedForPause(false), 143 paused(false) 144 { 145 } 146 }; 147 148 DeviceDescriptor* devices; 149 150 mutable class AudioDriverManager* audioDriverManager; 151 AudioDriverInterface* audioDriver; 152 153 bool initialized; 154 bool started; 155 bool paused; 156 157 void notifyListener(MasterMixerNotifications notification); 158 159 void cleanup(); 160 161 inline void prepareBuffer(); 162 inline void swapOutBuffer(mp_sword* bufferOut); 163 }; 164 165 #endif 166