clean up indentation and spacing
[supercollider.git] / server / supernova / audio_backend / audio_frontend.hpp
blob6714330a581a69071e7ad5cf339732667ed45e04
1 // audio frontend
2 // Copyright (C) 2005, 2006, 2007, 2008 Tim Blechmann
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; see the file COPYING. If not, write to
16 // the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 // Boston, MA 02111-1307, USA.
19 #ifndef _AUDIO_FRONTEND_HPP
20 #define _AUDIO_FRONTEND_HPP
22 #include <vector>
24 #include "audio_backend.hpp"
25 #include "portaudio.hpp"
26 #include "nova-tt/spin_lock.hpp"
27 #include <stdint.h>
29 namespace nova
32 /** \brief wrapper/dispatcher for different audio backends */
33 template <void(*dsp_cb)(void)>
34 class audio_frontend
36 typedef nova::dummy_backend<dsp_cb> dummy_backend;
38 public:
39 audio_frontend():
40 is_active(false)
42 activate_dummy();
45 ~audio_frontend(void)
47 assert(not audio_is_opened());
48 deactivate_dummy();
51 /* to be called from the audio callback */
52 /* @{ */
53 void deliver_dac_output(const_restricted_sample_ptr source, uint channel, uint frames)
55 if (likely(audio_is_active())) {
56 spin_lock::scoped_lock lock(output_lock);
57 active_backend->deliver_dac_output(source, channel, frames);
61 void zero_dac_output(uint channel, uint frames)
63 if (likely(audio_is_active())) {
64 spin_lock::scoped_lock lock(output_lock);
65 active_backend->zero_dac_output(channel, frames);
69 void deliver_dac_output_64(const_restricted_sample_ptr source, uint channel)
71 if (likely(audio_is_active())) {
72 spin_lock::scoped_lock lock(output_lock);
73 active_backend->deliver_dac_output_64(source, channel);
77 void fetch_adc_input(restricted_sample_ptr destination, uint channel, uint frames)
79 if (likely(audio_is_active()))
80 active_backend->fetch_adc_input(destination, channel, frames);
81 else {
82 if ((frames & (vec<F>::objects_per_cacheline - 1)) == 0)
83 zerovec_simd(destination, frames);
84 else
85 zerovec(destination, frames);
89 void fetch_adc_input_64(restricted_sample_ptr destination, uint channel)
91 if (likely(audio_is_active()))
92 active_backend->fetch_adc_input_64(destination, channel);
93 else
94 zerovec_simd_mp<64>(destination);
96 /* @} */
98 uint get_audio_blocksize(void)
100 assert(audio_is_active());
101 return active_backend->get_blocksize();
104 public:
105 std::vector<Device> list_devices(void)
107 return active_backend->list_devices();
110 void open_audio_stream(Device const & indevice, uint inchannels, Device const & outdevice, uint outchannels,
111 uint samplerate)
113 input_channels = inchannels,
114 output_channels = outchannels;
115 active_backend->open_audio_stream(indevice, inchannels, outdevice, outchannels, samplerate);
116 samplerate_ = samplerate;
119 void close_audio_stream(void)
121 active_backend->close_audio_stream();
122 input_channels = output_channels = 0;
125 bool audio_is_opened(void)
127 return active_backend != &dummy;
130 bool audio_is_ready(void)
132 return active_backend->audiostream_ready();
135 bool audio_is_active(void)
137 assert(active_backend->is_active() == is_active);
138 return is_active;
141 bool open_portaudio_backend(void)
143 assert(!audio_is_opened());
145 #ifdef HAVE_PORTAUDIO
146 deactivate_dummy();
147 active_backend = new portaudio_backend<dsp_cb>();
148 return true;
149 #else
150 return false;
151 #endif
154 void close_audio_backend(void)
156 assert(audio_is_opened());
158 if (active_backend->is_active())
159 active_backend->deactivate();
161 delete active_backend;
162 activate_dummy();
165 void activate_audio(void)
167 is_active = true;
168 active_backend->activate();
171 void deactivate_audio(void)
173 active_backend->deactivate();
174 is_active = false;
177 float get_samplerate(void) const
179 return samplerate_;
182 uint16_t get_input_count(void) const
184 return input_channels;
187 uint16_t get_output_count(void) const
189 return output_channels;
192 private:
193 void activate_dummy(void)
195 active_backend = &dummy;
197 device_list devs = dummy.list_devices();
198 dummy.open_audio_stream(devs[0], devs[0].inchannels,
199 devs[0], devs[0].outchannels,
200 devs[0].defaultSampleRate);
201 dummy.activate();
202 is_active = true;
205 void deactivate_dummy(void)
207 assert(!audio_is_opened());
208 dummy.deactivate();
209 dummy.close_audio_stream();
210 is_active = false;
213 bool is_active;
214 float samplerate_;
215 uint16_t input_channels, output_channels;
217 audio_backend<dsp_cb> * active_backend;
219 dummy_backend dummy; /* the dummy backend */
220 spin_lock output_lock;
223 } /* namespace nova */
226 #endif /* _AUDIO_FRONTEND_HPP */