arduino-audio-tools
Loading...
Searching...
No Matches
PortAudioStream.h
Go to the documentation of this file.
1#pragma once
8#include "AudioTools.h"
9#include "portaudio.h"
10
11namespace audio_tools {
12
17class PortAudioConfig : public AudioInfo {
18 public:
20 sample_rate = 44100;
21 channels = 2;
22 bits_per_sample = 16;
23 };
30
31 bool is_input = false;
32 bool is_output = true;
33};
34
44 public:
46
48 TRACED();
50 }
51
53 TRACED();
54 PortAudioConfig result;
55 switch (mode) {
56 case RX_MODE:
57 result.is_input = true;
58 result.is_output = false;
59 break;
60 case TX_MODE:
61 result.is_input = false;
62 result.is_output = true;
63 break;
64 case RXTX_MODE:
65 result.is_input = true;
66 result.is_output = true;
67 break;
68 default:
69 LOGE("Unsupported Mode")
70 break;
71 }
72
73 return result;
74 }
75
81
83 void setAudioInfo(AudioInfo in) override {
84 TRACEI();
88 info.logInfo();
89 begin(info);
90 };
91
92 // start with default configuration
93 bool begin() override { return begin(defaultConfig()); }
94
95 // start with the indicated configuration
97 TRACED();
98 this->info = info;
99
100 if (info.channels > 0 && info.sample_rate && info.bits_per_sample > 0) {
101 LOGD("Pa_Initialize");
102 err = Pa_Initialize();
103 LOGD("Pa_Initialize - done");
104 if (err != paNoError) {
105 LOGE("PortAudio error: %s\n", Pa_GetErrorText(err));
106 return false;
107 }
108
109 // calculate frames
110 int buffer_frames =
111 paFramesPerBufferUnspecified; // buffer_size / bytes / info.channels;
112
113 // Open an audio I/O stream.
114 LOGD("Pa_OpenDefaultStream");
116 &stream,
117 info.is_input ? info.channels : 0, // no input channels
118 info.is_output ? info.channels : 0, // no output
119 getFormat(), // format
120 info.sample_rate, // sample rate
121 buffer_frames, // frames per buffer
122 nullptr, nullptr);
123 LOGD("Pa_OpenDefaultStream - done");
124 if (err != paNoError && err != paOutputUnderflow) {
125 LOGE("PortAudio error: %s\n", Pa_GetErrorText(err));
126 return false;
127 }
128 } else {
129 LOGI("basic audio information is missing...");
130 return false;
131 }
132 return true;
133 }
134
135 void end() override {
136 TRACED();
138 if (err != paNoError) {
139 LOGE("PortAudio error: %s\n", Pa_GetErrorText(err));
140 }
141
143 if (err != paNoError) {
144 LOGE("PortAudio error: %s\n", Pa_GetErrorText(err));
145 }
146 stream_started = false;
147 }
148
149 operator bool() override { return err == paNoError; }
150
151 size_t write(const uint8_t* data, size_t len) override {
152 LOGD("write: %zu", len);
153
154 startStream();
155
156 size_t result = 0;
157 if (stream != nullptr) {
158 int frames = len / bytesPerSample() / info.channels;
159 err = Pa_WriteStream(stream, data, frames);
160 if (err == paNoError) {
161 LOGD("Pa_WriteStream: %zu", len);
162 result = len;
163 } else {
164 LOGE("PortAudio error: %s", Pa_GetErrorText(err));
165 }
166 } else {
167 LOGW("stream is null")
168 }
169 return result;
170 }
171
172 size_t readBytes(uint8_t* data, size_t len) override {
173 LOGD("readBytes: %zu", len);
174 size_t result = 0;
175 if (stream != nullptr) {
176 int frames = len / bytesPerSample() / info.channels;
177 err = Pa_ReadStream(stream, data, frames);
178 if (err == paNoError) {
179 result = len;
180 } else {
181 LOGE("PortAudio error: %s\n", Pa_GetErrorText(err));
182 }
183 } else {
184 LOGW("stream is null")
185 }
186 return len;
187 }
188
189 protected:
190 PaStream* stream = nullptr;
193 bool stream_started = false;
194 int buffer_size = 10 * 1024;
195
197 // return info.bits_per_sample / 8;
198 return info.bits_per_sample == 24 ? sizeof(int24_t)
199 : info.bits_per_sample / 8;
200 }
201
203 switch (bytesPerSample()) {
204 case 1:
205 return paInt8;
206 case 2:
207 return paInt16;
208 case 3:
209 return paInt24;
210 case 4:
211 return paInt32;
212 }
213 // make sure that we return a valid value
214 return paInt16;
215 }
216
218 void startStream() {
219 if (!stream_started && stream != nullptr) {
220 TRACED();
222 if (err == paNoError) {
223 stream_started = true;
224 } else {
225 stream_started = false;
226 LOGE("PortAudio error: %s\n", Pa_GetErrorText(err));
227 }
228 }
229 }
230};
231
232} // namespace audio_tools
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define TRACEI()
Definition AudioLoggerIDF.h:32
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
Base class for all Audio Streams. It support the boolean operator to test if the object is ready with...
Definition BaseStream.h:120
PortAudio information.
Definition PortAudioStream.h:17
PortAudioConfig()
Definition PortAudioStream.h:19
PortAudioConfig(const PortAudioConfig &)=default
bool is_output
Definition PortAudioStream.h:32
PortAudioConfig(const AudioInfo &in)
Definition PortAudioStream.h:25
bool is_input
Definition PortAudioStream.h:31
Arduino Audio Stream using PortAudio.
Definition PortAudioStream.h:43
PaSampleFormat getFormat()
Definition PortAudioStream.h:202
PortAudioConfig defaultConfig()
Definition PortAudioStream.h:76
bool stream_started
Definition PortAudioStream.h:193
~PortAudioStream()
Definition PortAudioStream.h:47
PortAudioConfig info
Definition PortAudioStream.h:192
size_t readBytes(uint8_t *data, size_t len) override
Definition PortAudioStream.h:172
void end() override
Definition PortAudioStream.h:135
size_t write(const uint8_t *data, size_t len) override
Definition PortAudioStream.h:151
int bytesPerSample()
Definition PortAudioStream.h:196
void startStream()
automatically start the stream when we start to get data
Definition PortAudioStream.h:218
PaStream * stream
Definition PortAudioStream.h:190
PortAudioConfig defaultConfig(RxTxMode mode)
Definition PortAudioStream.h:52
bool begin(PortAudioConfig info)
Definition PortAudioStream.h:96
PaError err
Definition PortAudioStream.h:191
void setAudioInfo(AudioInfo in) override
notification of audio info change
Definition PortAudioStream.h:83
bool begin() override
Definition PortAudioStream.h:93
PortAudioStream()
Definition PortAudioStream.h:45
int buffer_size
Definition PortAudioStream.h:194
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition AudioTypes.h:26
@ RXTX_MODE
Definition AudioTypes.h:26
@ TX_MODE
Definition AudioTypes.h:26
@ RX_MODE
Definition AudioTypes.h:26
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
int24_4bytes_t int24_t
Definition int24_t.h:12
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:508
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:51
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:53
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:55
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:57
virtual void logInfo(const char *source="")
Definition AudioTypes.h:121