Discman
Loading...
Searching...
No Matches
audio_output.h
Go to the documentation of this file.
1
6
7 #ifndef AUDIO_OUTPUT_H
8#define AUDIO_OUTPUT_H
9
10#include <iostream>
11#include <portaudio.h>
12#include <stdint.h>
13
15
19template <typename T>
20class AudioOutput : public Consumer<T> {
21 public:
22
29
30 static void init();
31 static void destroy();
32 static void restart();
33
34 static void start();
35 static void stop();
36
41 static bool isDefault();
42
45 static constexpr int SAMPLE_RATE = 44100;
46
47 private:
49
50 static PaError _pa_error;
51 static PaStream* _pa_stream;
52
54
64 static int pa_callback(const void* input_buffer,
65 void* output_buffer,
66 unsigned long frames_per_buffer,
67 const PaStreamCallbackTimeInfo* time_info,
68 PaStreamCallbackFlags status_flags,
69 void* user_data);
70};
71
75template <typename T>
77
78template <typename T>
80template <typename T>
82
83template <typename T>
91
92template <typename T>
94 _pa_error = Pa_Initialize();
95 if( _pa_error != paNoError ) {
96 std::cerr << "PortAudio error: " << Pa_GetErrorText( _pa_error ) << std::endl;
97 return;
98 }
99
100 PaSampleFormat format;
101 if constexpr (std::is_same_v<T, int16_t>)
102 format = paInt16;
103 else if constexpr (std::is_same_v<T, float>)
104 format = paFloat32;
105
106 /* Open an audio I/O stream. */
107 _pa_error = Pa_OpenDefaultStream( &_pa_stream,
108 0, /* no input channels */
109 2, /* stereo output */
110 format,
112 256, /* frames per buffer, i.e. the number
113 of sample frames that PortAudio will
114 request from the callback. Many apps
115 may want to use
116 paframes_per_bufferUnspecified, which
117 tells PortAudio to pick the best,
118 possibly changing, buffer size.*/
119 &pa_callback, /* this is your callback function */
120 nullptr); /*This is a pointer that will be passed to
121 your callback*/
122 if( _pa_error != paNoError ) {
123 std::cerr << "PortAudio error: " << Pa_GetErrorText( _pa_error ) << std::endl;
124 return;
125 }
126}
127
128template <typename T>
130 _pa_error = Pa_CloseStream( _pa_stream );
131 if( _pa_error != paNoError ) {
132 std::cerr << "PortAudio error: " << Pa_GetErrorText( _pa_error ) << std::endl;
133 return;
134 }
135
136 _pa_error = Pa_Terminate();
137 if( _pa_error != paNoError ) {
138 std::cerr << "PortAudio error: " << Pa_GetErrorText( _pa_error ) << std::endl;
139 return;
140 }
141
142 delete _instance;
143}
144
145template <typename T>
147 _pa_error = Pa_StartStream( _pa_stream );
148 if( _pa_error != paNoError ) {
149 std::cerr << "PortAudio error: " << Pa_GetErrorText( _pa_error ) << std::endl;
150 return;
151 }
152}
153
154template <typename T>
156 _pa_error = Pa_StopStream( _pa_stream );
157 if( _pa_error != paNoError ) {
158 std::cerr << "PortAudio error: " << Pa_GetErrorText( _pa_error ) << std::endl;
159 return;
160 }
161}
162
163template <typename T>
165 _pa_error = Pa_CloseStream( _pa_stream );
166 if( _pa_error != paNoError ) {
167 std::cerr << "PortAudio error: " << Pa_GetErrorText( _pa_error ) << std::endl;
168 return;
169 }
170
171 _pa_error = Pa_Terminate();
172 if( _pa_error != paNoError ) {
173 std::cerr << "PortAudio error: " << Pa_GetErrorText( _pa_error ) << std::endl;
174 return;
175 }
176
177 init();
178}
179
180template <typename T>
182 return Pa_GetDefaultOutputDevice() == 0;
183}
184
185template <typename T>
186int AudioOutput<T>::pa_callback(const void* input_buffer,
187 void* output_buffer,
188 unsigned long frames_per_buffer,
189 const PaStreamCallbackTimeInfo* time_info,
190 PaStreamCallbackFlags status_flags,
191 void* user_data) {
192 T* out = (T*)output_buffer;
193 unsigned int i;
194 (void) input_buffer; /* Prevent unused variable warning. */
195 (void) user_data;
196
197 for( i=0; i<frames_per_buffer; i++ )
198 {
199 *out++ = instance()->consume(); // left
200 *out++ = instance()->consume(); // right
201 }
202
203 return 0;
204}
205
206#endif // AUDIO_OUTPUT_H
Abstracts PortAudio using a given audio sample data type.
static void start()
Starts the invokation of the PortAudio callback.
static PaStream * _pa_stream
The PortAudio stream.
static void init()
Initializes PortAudio.
static AudioOutput * _instance
The global AudioOutput instance.
static constexpr int SAMPLE_RATE
The AudioOutput sample rate, which is matched to the sample rate of CD audio.
static bool isDefault()
Returns whether the default audio output device is used. This indicates that a Bluetooth device is no...
static PaError _pa_error
The most recent PortAudio error.
static int pa_callback(const void *input_buffer, void *output_buffer, unsigned long frames_per_buffer, const PaStreamCallbackTimeInfo *time_info, PaStreamCallbackFlags status_flags, void *user_data)
The PortAudio callback.
static void destroy()
Tears down PortAudio.
static void restart()
Restarts PortAudio.
static AudioOutput * instance()
Factory method to return the AudioOutput. It may be called one or more times. Be sure to destroy() th...
static void stop()
Stops the invokation of the PortAudio callback.
Consumer()
Consumer constructor.
Definition consumer.h:38