YARP
Yet Another Robot Platform
PortAudioDeviceDriver.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library 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 GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "PortAudioDeviceDriver.h"
20 
21 #include <cstdio>
22 #include <cstdlib>
23 #include <cstring>
24 #include <portaudio.h>
25 #include <yarp/dev/DeviceDriver.h>
26 #include <yarp/dev/api.h>
27 
28 #include <yarp/os/Time.h>
29 #include <yarp/os/LogComponent.h>
30 #include <yarp/os/LogStream.h>
31 
32 using namespace yarp::os;
33 using namespace yarp::dev;
34 
35 #define SLEEP_TIME 0.005f
36 
37 #if 0
38 #define PA_SAMPLE_TYPE paFloat32
39 typedef float SAMPLE;
40 #define SAMPLE_SILENCE (0.0f)
41 #elif 1
42 #define PA_SAMPLE_TYPE paInt16
43 typedef short SAMPLE;
44 #define SAMPLE_SILENCE (0)
45 #elif 1
46 #define PA_SAMPLE_TYPE paInt8
47 typedef char SAMPLE;
48 #define SAMPLE_SILENCE (0)
49 #else
50 #define PA_SAMPLE_TYPE paUInt8
51 typedef unsigned char SAMPLE;
52 #define SAMPLE_SILENCE (128)
53 #define SAMPLE_UNSIGNED
54 #endif
55 
56 namespace {
57 YARP_LOG_COMPONENT(PORTAUDIO, "yarp.devices.portaudio")
58 }
59 
60 /* This routine will be called by the PortAudio engine when audio is needed.
61 ** It may be called at interrupt level on some machines so don't do anything
62 ** that could mess up the system like calling malloc() or free().
63 */
64 static int bufferIOCallback( const void *inputBuffer, void *outputBuffer,
65  unsigned long framesPerBuffer,
66  const PaStreamCallbackTimeInfo* timeInfo,
67  PaStreamCallbackFlags statusFlags,
68  void *userData )
69 {
70  auto* dataBuffers = static_cast<circularDataBuffers*>(userData);
71  CircularAudioBuffer_16t *playdata = dataBuffers->playData;
72  CircularAudioBuffer_16t *recdata = dataBuffers->recData;
73  int num_rec_channels = dataBuffers->numRecChannels;
74  int num_play_channels = dataBuffers->numPlayChannels;
75  int finished = paComplete;
76 
77  if (dataBuffers->canRec)
78  {
79  const auto* rptr = (const SAMPLE*)inputBuffer;
80  unsigned int framesToCalc;
81  unsigned int i;
82  size_t framesLeft = (recdata->getMaxSize().getSamples()* recdata->getMaxSize().getChannels()) -
83  (recdata->size().getSamples() * recdata->size().getChannels());
84 
85  (void) outputBuffer; // just to prevent unused variable warnings
86  (void) timeInfo;
87  (void) statusFlags;
88  (void) userData;
89 
90  if( framesLeft/ num_rec_channels < framesPerBuffer )
91  {
92  framesToCalc = framesLeft/ num_rec_channels;
93 #ifdef STOP_REC_ON_EMPTY_BUFFER
94  //if we return paComplete, then the callback is not called anymore.
95  //method Pa_IsStreamActive() will return 1.
96  //user needs to call Pa_StopStream() before starting a new recording session
97  finished = paComplete;
98 #else
99  finished = paContinue;
100 #endif
101  }
102  else
103  {
104  framesToCalc = framesPerBuffer;
105  //if we return paContinue, then the callback will be invoked again later
106  //method Pa_IsStreamActive() will return 0
107  finished = paContinue;
108  }
109 
110  if( inputBuffer == nullptr )
111  {
112  for( i=0; i<framesToCalc; i++ )
113  {
114  recdata->write(0); // left
115  if(num_rec_channels == 2 ) recdata->write(0); // right
116  }
117  }
118  else
119  {
120  yCTrace(PORTAUDIO) << "Writing" << framesToCalc*2*2 << "bytes in the circular buffer";
121  for( i=0; i<framesToCalc; i++ )
122  {
123  recdata->write(*rptr++); // left
124  if(num_rec_channels == 2 ) recdata->write(*rptr++); // right
125  }
126  }
127  //note: you can record or play but not simultaneously (for now)
128  return finished;
129  }
130 
131  if (dataBuffers->canPlay)
132  {
133  auto* wptr = (SAMPLE*)outputBuffer;
134  unsigned int i;
135 
136  size_t framesLeft = playdata->size().getSamples()* playdata->size().getChannels();
137 
138  (void) inputBuffer; // just to prevent unused variable warnings
139  (void) timeInfo;
140  (void) statusFlags;
141  (void) userData;
142 
143  if( framesLeft/ num_play_channels < framesPerBuffer )
144  {
145  // final buffer
146  for( i=0; i<framesLeft/ num_play_channels; i++ )
147  {
148  *wptr++ = playdata->read(); // left
149  if( num_play_channels == 2 ) *wptr++ = playdata->read(); // right
150  for (int chs=2; chs<num_play_channels; chs++) playdata->read(); //remove all additional channels > 2
151  }
152  for( ; i<framesPerBuffer; i++ )
153  {
154  *wptr++ = 0; // left
155  if(num_play_channels == 2 ) *wptr++ = 0; // right
156  }
157 #ifdef STOP_PLAY_ON_EMPTY_BUFFER
158  //if we return paComplete, then the callback is not called anymore.
159  //method Pa_IsStreamActive() will return 1.
160  //user needs to call Pa_StopStream() before starting a new recording session
161  finished = paComplete;
162 #else
163  finished = paContinue;
164 #endif
165  }
166  else
167  {
168 #if 1
169  yCDebug(PORTAUDIO) << "Reading" << framesPerBuffer*2 << "bytes from the circular buffer";
170 #endif
171  for( i=0; i<framesPerBuffer; i++ )
172  {
173  *wptr++ = playdata->read(); // left
174  if( num_play_channels == 2 ) *wptr++ = playdata->read(); // right
175  for (int chs=2; chs<num_play_channels; chs++) playdata->read(); //remove all additional channels > 2
176  }
177  //if we return paContinue, then the callback will be invoked again later
178  //method Pa_IsStreamActive() will return 0
179  finished = paContinue;
180  }
181  //note: you can record or play but not simultaneously (for now)
182  return finished;
183  }
184 
185  yCError(PORTAUDIO, "No read/write operations requested, aborting");
186  return paAbort;
187 }
188 
190  stream(nullptr),
191  err(paNoError),
192  numSamples(0),
193  numBytes(0),
194  m_system_resource(nullptr),
195  m_numPlaybackChannels(0),
196  m_numRecordChannels(0),
197  m_frequency(0),
198  m_loopBack(false),
199  m_getSoundIsNotBlocking(true),
200  renderMode(RENDER_APPEND)
201 {
202  memset(&inputParameters, 0, sizeof(PaStreamParameters));
203  memset(&outputParameters, 0, sizeof(PaStreamParameters));
204  memset(&m_driverConfig, 0, sizeof(PortAudioDeviceDriverSettings));
205 }
206 
208 {
209  close();
210 }
211 
212 
214 {
215  m_driverConfig.rate = config.check("rate",Value(0),"audio sample rate (0=automatic)").asInt32();
216  m_driverConfig.samples = config.check("samples",Value(0),"number of samples per network packet (0=automatic). For chunks of 1 second of recording set samples=rate. Channels number is handled internally.").asInt32();
217  m_driverConfig.playChannels = config.check("channels",Value(0),"number of audio channels (0=automatic, max is 2)").asInt32();
218  m_driverConfig.recChannels = config.check("channels", Value(0), "number of audio channels (0=automatic, max is 2)").asInt32();
219  m_driverConfig.wantRead = (bool)config.check("read","if present, just deal with reading audio (microphone)");
220  m_driverConfig.wantWrite = (bool)config.check("write","if present, just deal with writing audio (speaker)");
221  m_driverConfig.deviceNumber = config.check("id",Value(-1),"which portaudio index to use (-1=automatic)").asInt32();
222 
224  {
226  }
227 
228  if (config.check("loopback","if present, send audio read from microphone immediately back to speaker"))
229  {
230  yError ("loopback not yet implemented");
231  m_loopBack = true;
232  }
233 
234  if (config.check("render_mode_append"))
235  {
237  }
238  if (config.check("render_mode_immediate"))
239  {
241  }
242 
243  return open(m_driverConfig);
244 }
245 
247 {
248  int rate = config.rate;
249  int samples = config.samples;
250  int playChannels = config.playChannels;
251  int recChannels = config.recChannels;
252  bool wantRead = config.wantRead;
253  bool wantWrite = config.wantWrite;
254  int deviceNumber = config.deviceNumber;
255 
256  if (playChannels==0) playChannels = DEFAULT_NUM_CHANNELS;
257  if (recChannels == 0) recChannels = DEFAULT_NUM_CHANNELS;
258  m_numPlaybackChannels = playChannels;
259  m_numRecordChannels = recChannels;
260 
261  if (rate==0) rate = DEFAULT_SAMPLE_RATE;
262  m_frequency = rate;
263 
264  if (samples==0)
265  numSamples = m_frequency; // by default let's stream chunks of 1 second
266  else
267  numSamples = samples;
268 
269 // size_t numPlayBytes = numSamples * sizeof(SAMPLE) * m_numPlaybackChannels;
270 // size_t numRecBytes = numSamples * sizeof(SAMPLE) * m_numRecordChannels;
271 // int twiceTheBuffer = 2;
272  AudioBufferSize playback_buffer_size(numSamples, m_numPlaybackChannels, sizeof(SAMPLE));
273  AudioBufferSize rec_buffer_size (numSamples, m_numRecordChannels, sizeof(SAMPLE));
275  dataBuffers.numRecChannels = m_numRecordChannels;
276  if (dataBuffers.playData==nullptr)
277  dataBuffers.playData = new CircularAudioBuffer_16t("portatudio_play", playback_buffer_size);
278  if (dataBuffers.recData==nullptr)
279  dataBuffers.recData = new CircularAudioBuffer_16t("portatudio_rec", rec_buffer_size);
280  if (wantRead) dataBuffers.canRec = true;
281  if (wantWrite) dataBuffers.canPlay = true;
282 
283  err = Pa_Initialize();
284  if( err != paNoError )
285  {
286  yCError(PORTAUDIO, "portaudio system failed to initialize");
287  return false;
288  }
289 
290  inputParameters.device = (deviceNumber==-1)?Pa_GetDefaultInputDevice():deviceNumber;
291  yCInfo(PORTAUDIO, "Device number %d", inputParameters.device);
292  inputParameters.channelCount = m_numRecordChannels;
293  inputParameters.sampleFormat = PA_SAMPLE_TYPE;
294  if ((Pa_GetDeviceInfo( inputParameters.device ))!=nullptr) {
295  inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
296  }
297  inputParameters.hostApiSpecificStreamInfo = nullptr;
298 
299  outputParameters.device = (deviceNumber==-1)?Pa_GetDefaultOutputDevice():deviceNumber;
300  outputParameters.channelCount = m_numPlaybackChannels;
301  outputParameters.sampleFormat = PA_SAMPLE_TYPE;
302  outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
303  outputParameters.hostApiSpecificStreamInfo = nullptr;
304 
305  err = Pa_OpenStream(
306  &stream,
307  wantRead?(&inputParameters):nullptr,
308  wantWrite?(&outputParameters):nullptr,
309  m_frequency,
311  paClipOff,
313  &dataBuffers );
314 
315  if( err != paNoError )
316  {
317  yCError(PORTAUDIO, "An error occurred while using the portaudio stream");
318  yCError(PORTAUDIO, "Error number: %d", err);
319  yCError(PORTAUDIO, "Error message: %s", Pa_GetErrorText(err));
320  }
321 
322  //start the thread
323  pThread.stream = stream;
324  pThread.start();
325 
326  return (err==paNoError);
327 }
328 
329 void streamThread::handleError()
330 {
331  Pa_Terminate();
332  if( err != paNoError )
333  {
334  yCError(PORTAUDIO, "An error occurred while using the portaudio stream");
335  yCError(PORTAUDIO, "Error number: %d", err);
336  yCError(PORTAUDIO, "Error message: %s\n", Pa_GetErrorText(err));
337  }
338 }
339 
341 {
342  //Pa_Terminate();
343  dataBuffers.playData->clear();
344 
345  if( err != paNoError )
346  {
347  yCError(PORTAUDIO, "An error occurred while using the portaudio stream");
348  yCError(PORTAUDIO, "Error number: %d", err);
349  yCError(PORTAUDIO, "Error message: %s", Pa_GetErrorText(err));
350  }
351 }
352 
354 {
355  pThread.stop();
356  if (stream != nullptr)
357  {
358  err = Pa_CloseStream( stream );
359  if( err != paNoError )
360  {
361  yCError(PORTAUDIO, "An error occurred while closing the portaudio stream");
362  yCError(PORTAUDIO, "Error number: %d", err);
363  yCError(PORTAUDIO, "Error message: %s", Pa_GetErrorText(err));
364  }
365  }
366 
367  if (this->dataBuffers.playData != nullptr)
368  {
369  delete this->dataBuffers.playData;
370  this->dataBuffers.playData = nullptr;
371  }
372  if (this->dataBuffers.recData != nullptr)
373  {
374  delete this->dataBuffers.recData;
375  this->dataBuffers.recData = nullptr;
376  }
377 
378  return (err==paNoError);
379 }
380 
382 {
383  pThread.something_to_record = true;
384  err = Pa_StartStream( stream );
385  if( err < 0 ) {handleError(); return false;}
386  return true;
387 }
388 
390 {
391  pThread.something_to_record = false;
392  err = Pa_StopStream( stream );
393  if( err < 0 ) {handleError(); return false;}
394  return true;
395 }
396 
397 bool PortAudioDeviceDriver::getSound(yarp::sig::Sound& sound, size_t min_number_of_samples, size_t max_number_of_samples, double max_samples_timeout_s)
398 {
399  if (pThread.something_to_record == false)
400  {
401  this->startRecording();
402  }
403 
404  size_t buff_size = 0;
405  int buff_size_wdt = 0;
406  do
407  {
408  buff_size = dataBuffers.recData->size().getSamples();
409 
410  if (buff_size_wdt > 100)
411  {
412  if (buff_size == 0)
413  {
414  yCError(PORTAUDIO) << "PortAudioDeviceDriver::getSound() Buffer size is still zero after 100 iterations, returning";
415  return false;
416  }
417  else
418  {
419  yCDebug(PORTAUDIO) << "PortAudioDeviceDriver::getSound() Buffer size is " << buff_size << "/" << this->numSamples <<" after 100 iterations";
421  {
422  yCError(PORTAUDIO) << "PortAudioDeviceDriver::getSound() is in not-blocking mode, returning";
423  return false;
424  }
425  }
426  }
427  buff_size_wdt++;
429  }
430  while (buff_size < this->numSamples);
431 
432  buff_size_wdt = 0;
433 
434  if (sound.getChannels()!=this->m_numRecordChannels && sound.getSamples() != this->numSamples)
435  {
436  sound.resize(this->numSamples,this->m_numRecordChannels);
437  }
438  sound.setFrequency(this->m_frequency);
439 
440  for (size_t i=0; i<this->numSamples; i++)
441  for (size_t j=0; j<this->m_numRecordChannels; j++)
442  {
443  SAMPLE s = dataBuffers.recData->read();
444  sound.set(s,i,j);
445  }
446  return true;
447 }
448 
450 {
451  yCInfo(PORTAUDIO, "=== Stopping and clearing stream.==="); fflush(stdout);
452  err = Pa_StopStream( stream );
453  if( err != paNoError )
454  {
455  yCError(PORTAUDIO, "abortSound: error occurred while stopping the portaudio stream" );
456  yCError(PORTAUDIO, "Error number: %d", err );
457  yCError(PORTAUDIO, "Error message: %s", Pa_GetErrorText( err ) );
458  }
459 
460  dataBuffers.playData->clear();
461 
462  return (err==paNoError);
463 }
464 
466 {
467 }
468 
470 {
471  something_to_play=false;
472  something_to_record=false;
473  err = paNoError;
474  return true;
475 }
476 
478 {
479  while(this->isStopping()==false)
480  {
481  if( something_to_play )
482  {
483  something_to_play = false;
484  err = Pa_StartStream( stream );
485  if( err != paNoError ) {handleError(); return;}
486 
487  while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
488  {
490  }
491  if (err == 0)
492  {
493  yCDebug(PORTAUDIO) << "The playback stream has been stopped";
494  }
495  if( err < 0 )
496  {
497  handleError();
498  return;
499  }
500 
501  err = Pa_StopStream( stream );
502  //err = Pa_AbortStream( stream );
503  if( err < 0 )
504  {
505  handleError();
506  return;
507  }
508 
509  }
510 
512  {
513  while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
514  {
516  }
517  if (err == 0)
518  {
519  Pa_StopStream(stream);
520  yCDebug(PORTAUDIO) << "The recording stream has been stopped";
521  something_to_record = false;
522  }
523  if( err < 0 )
524  {
525  handleError();
526  return;
527  }
528  }
529 
531  }
532  return;
533 }
534 
536 {
537  dataBuffers.playData->clear();
538 
539 // size_t num_bytes = sound.getBytesPerSample();
540  size_t num_channels = sound.getChannels();
541  size_t num_samples = sound.getSamples();
542 
543  for (size_t i=0; i<num_samples; i++)
544  for (size_t j=0; j<num_channels; j++)
545  dataBuffers.playData->write (sound.get(i,j));
546 
547  pThread.something_to_play = true;
548  return true;
549 }
550 
552 {
553  int freq = sound.getFrequency();
554  size_t chans = sound.getChannels();
555  if (freq != this->m_frequency ||
556  chans != this->m_numPlaybackChannels)
557  {
558  //wait for current playback to finish
559  while (Pa_IsStreamStopped(stream )==0)
560  {
562  }
563 
564  //reset the driver
565  yCInfo(PORTAUDIO, "***** audio driver configuration changed, resetting");
566  yCInfo(PORTAUDIO) << "changing from: " << this->m_numPlaybackChannels << "channels, " << this->m_frequency << " Hz, ->" <<
567  chans << "channels, " << freq << " Hz";
568  this->close();
569  m_driverConfig.playChannels = (int)(chans);
570  m_driverConfig.rate = (int)(freq);
571  bool ok = open(m_driverConfig);
572  if (ok == false)
573  {
574  yCError(PORTAUDIO, "error occurred during audio driver reconfiguration, aborting");
575  return false;
576  }
577  }
578 
580  return immediateSound(sound);
581  else if (renderMode == RENDER_APPEND)
582  return appendSound(sound);
583 
584  return false;
585 }
586 
588 {
589 // size_t num_bytes = sound.getBytesPerSample();
590  size_t num_channels = sound.getChannels();
591  size_t num_samples = sound.getSamples();
592 
593  for (size_t i=0; i<num_samples; i++)
594  for (size_t j=0; j<num_channels; j++)
595  dataBuffers.playData->write (sound.get(i,j));
596 
597  pThread.something_to_play = true;
598  return true;
599 }
600 
602 {
603  size = this->dataBuffers.playData->size();
604  return true;
605 }
606 
608 {
609  size = this->dataBuffers.playData->getMaxSize();
610  return true;
611 }
612 
614 {
615  this->dataBuffers.playData->clear();
616  return true;
617 }
618 
620 {
621  size = this->dataBuffers.recData->size();
622  return true;
623 }
624 
626 {
627  size = this->dataBuffers.recData->getMaxSize();
628  return true;
629 }
630 
632 {
633  this->dataBuffers.recData->clear();
634  return true;
635 }
636 
638 {
639  pThread.something_to_play = true;
640  return true;
641 }
642 
644 {
645  pThread.something_to_play = false;
646  return true;
647 }
LogStream.h
streamThread::stream
PaStream * stream
Definition: PortAudioDeviceDriver.h:55
yarp::sig::Sound::setFrequency
void setFrequency(int freq)
Set the frequency of the sound (i.e.
Definition: Sound.cpp:226
streamThread::run
void run() override
Main body of the new thread.
Definition: PortAudioDeviceDriver.cpp:477
PortAudioDeviceDriverSettings::recChannels
int recChannels
Definition: PortAudioDeviceDriver.h:43
PortAudioDeviceDriver::stopPlayback
bool stopPlayback() override
Stop the playback.
Definition: PortAudioDeviceDriver.cpp:643
yarp::dev::CircularAudioBuffer::write
void write(SAMPLE elem)
Definition: CircularAudioBuffer.h:48
DEFAULT_FRAMES_PER_BUFFER
#define DEFAULT_FRAMES_PER_BUFFER
Definition: PortAudioDeviceDriver.h:33
api.h
yarp::dev::CircularAudioBuffer::clear
void clear()
Definition: CircularAudioBuffer.h:87
PortAudioDeviceDriver::renderMode
enum PortAudioDeviceDriver::@90 renderMode
PortAudioDeviceDriver::startPlayback
bool startPlayback() override
Start the playback.
Definition: PortAudioDeviceDriver.cpp:637
yarp::os::Searchable
A base class for nested structures that can be searched.
Definition: Searchable.h:68
yarp::sig::Sound::getFrequency
int getFrequency() const
Get the frequency of the sound (i.e.
Definition: Sound.cpp:221
PA_SAMPLE_TYPE
#define PA_SAMPLE_TYPE
Definition: PortAudioDeviceDriver.cpp:42
SLEEP_TIME
#define SLEEP_TIME
Definition: PortAudioDeviceDriver.cpp:35
PortAudioDeviceDriver::handleError
void handleError(void)
Definition: PortAudioDeviceDriver.cpp:340
yarp::sig::Sound::getSamples
size_t getSamples() const
Get the number of samples contained in the sound.
Definition: Sound.cpp:404
PortAudioDeviceDriverSettings
Definition: PortAudioDeviceDriver.h:37
yarp::dev::AudioBufferSize
Definition: AudioBufferSize.h:24
yarp::dev::AudioBufferSize::getChannels
size_t getChannels()
Definition: AudioBufferSize.h:32
PortAudioDeviceDriver::m_getSoundIsNotBlocking
bool m_getSoundIsNotBlocking
Definition: PortAudioDeviceDriver.h:134
PortAudioDeviceDriver::resetRecordingAudioBuffer
bool resetRecordingAudioBuffer() override
Definition: PortAudioDeviceDriver.cpp:631
YARP_LOG_COMPONENT
#define YARP_LOG_COMPONENT(name,...)
Definition: LogComponent.h:80
circularDataBuffers::numPlayChannels
size_t numPlayChannels
Definition: PortAudioBuffer.h:34
PortAudioDeviceDriver::m_driverConfig
PortAudioDeviceDriverSettings m_driverConfig
Definition: PortAudioDeviceDriver.h:136
PortAudioDeviceDriver::m_numRecordChannels
size_t m_numRecordChannels
Definition: PortAudioDeviceDriver.h:131
PortAudioDeviceDriverSettings::playChannels
int playChannels
Definition: PortAudioDeviceDriver.h:42
PortAudioDeviceDriver::~PortAudioDeviceDriver
virtual ~PortAudioDeviceDriver()
Definition: PortAudioDeviceDriver.cpp:207
PortAudioDeviceDriver::RENDER_IMMEDIATE
@ RENDER_IMMEDIATE
Definition: PortAudioDeviceDriver.h:137
samples
int16_t * samples
Definition: FfmpegWriter.cpp:71
circularDataBuffers::recData
yarp::dev::CircularAudioBuffer_16t * recData
Definition: PortAudioBuffer.h:31
yarp::sig::Sound::getChannels
size_t getChannels() const
Get the number of channels of the sound.
Definition: Sound.cpp:409
PortAudioDeviceDriver::startRecording
bool startRecording() override
Start the recording.
Definition: PortAudioDeviceDriver.cpp:381
yError
#define yError(...)
Definition: Log.h:242
yarp::dev
An interface for the device drivers.
Definition: audioBufferSizeData.cpp:17
PortAudioDeviceDriverSettings::deviceNumber
int deviceNumber
Definition: PortAudioDeviceDriver.h:46
yarp::dev::CircularAudioBuffer
Definition: AudioBufferSize.h:22
PortAudioDeviceDriver::getSound
bool getSound(yarp::sig::Sound &sound, size_t min_number_of_samples, size_t max_number_of_samples, double max_samples_timeout_s) override
Get a sound from a device.
Definition: PortAudioDeviceDriver.cpp:397
PortAudioDeviceDriver.h
PortAudioDeviceDriver::stopRecording
bool stopRecording() override
Stop the recording.
Definition: PortAudioDeviceDriver.cpp:389
yarp::dev::CircularAudioBuffer::size
AudioBufferSize size()
Definition: CircularAudioBuffer.h:59
PortAudioDeviceDriver::abortSound
bool abortSound(void)
Definition: PortAudioDeviceDriver.cpp:449
streamThread::something_to_play
bool something_to_play
Definition: PortAudioDeviceDriver.h:53
PortAudioDeviceDriver::m_loopBack
bool m_loopBack
Definition: PortAudioDeviceDriver.h:133
yarp::os::SystemClock::delaySystem
static void delaySystem(double seconds)
Definition: SystemClock.cpp:32
PortAudioDeviceDriver::getPlaybackAudioBufferMaxSize
bool getPlaybackAudioBufferMaxSize(yarp::dev::AudioBufferSize &size) override
Definition: PortAudioDeviceDriver.cpp:607
PortAudioDeviceDriver::PortAudioDeviceDriver
PortAudioDeviceDriver()
Definition: PortAudioDeviceDriver.cpp:189
PortAudioDeviceDriver::getRecordingAudioBufferCurrentSize
bool getRecordingAudioBufferCurrentSize(yarp::dev::AudioBufferSize &size) override
Definition: PortAudioDeviceDriver.cpp:619
yarp::sig::Sound::set
void set(audio_sample value, size_t sample, size_t channel=0)
Definition: Sound.cpp:206
yarp::os::Searchable::check
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
circularDataBuffers::numRecChannels
size_t numRecChannels
Definition: PortAudioBuffer.h:35
yarp::sig::Sound::get
audio_sample get(size_t sample, size_t channel=0) const
Definition: Sound.cpp:174
PortAudioDeviceDriver::resetPlaybackAudioBuffer
bool resetPlaybackAudioBuffer() override
Definition: PortAudioDeviceDriver.cpp:613
circularDataBuffers::canRec
bool canRec
Definition: PortAudioBuffer.h:33
PortAudioDeviceDriverSettings::rate
int rate
Definition: PortAudioDeviceDriver.h:40
yarp::dev::AudioBufferSize::getSamples
size_t getSamples()
Definition: AudioBufferSize.h:31
LogComponent.h
PortAudioDeviceDriver::getPlaybackAudioBufferCurrentSize
bool getPlaybackAudioBufferCurrentSize(yarp::dev::AudioBufferSize &size) override
Definition: PortAudioDeviceDriver.cpp:601
PortAudioDeviceDriver::renderSound
bool renderSound(const yarp::sig::Sound &sound) override
Render a sound using a device (i.e.
Definition: PortAudioDeviceDriver.cpp:551
PortAudioDeviceDriver::immediateSound
bool immediateSound(const yarp::sig::Sound &sound)
Definition: PortAudioDeviceDriver.cpp:535
circularDataBuffers::playData
yarp::dev::CircularAudioBuffer_16t * playData
Definition: PortAudioBuffer.h:30
circularDataBuffers::canPlay
bool canPlay
Definition: PortAudioBuffer.h:32
PortAudioDeviceDriver::close
bool close(void) override
Close the DeviceDriver.
Definition: PortAudioDeviceDriver.cpp:353
yCError
#define yCError(component,...)
Definition: LogComponent.h:127
yarp::os::Thread::isStopping
bool isStopping()
Returns true if the thread is stopping (Thread::stop has been called).
Definition: Thread.cpp:102
PortAudioDeviceDriver::m_numPlaybackChannels
size_t m_numPlaybackChannels
Definition: PortAudioDeviceDriver.h:130
yCInfo
#define yCInfo(component,...)
Definition: LogComponent.h:115
yarp::os
Definition: AbstractCarrier.h:17
yCDebug
#define yCDebug(component,...)
Definition: LogComponent.h:102
yarp::sig::Sound
Definition: Sound.h:27
DEFAULT_NUM_CHANNELS
#define DEFAULT_NUM_CHANNELS
Definition: PortAudioDeviceDriver.h:31
bufferIOCallback
static int bufferIOCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
Definition: PortAudioDeviceDriver.cpp:64
PortAudioDeviceDriverSettings::samples
int samples
Definition: PortAudioDeviceDriver.h:41
PortAudioDeviceDriver::m_frequency
int m_frequency
Definition: PortAudioDeviceDriver.h:132
yarp::dev::CircularAudioBuffer_16t
yarp::dev::CircularAudioBuffer< unsigned short int > CircularAudioBuffer_16t
Definition: CircularAudioBuffer.h:118
yarp::sig::Sound::resize
void resize(size_t samples, size_t channels=1)
Set the sound size.
Definition: Sound.cpp:167
yarp::dev::CircularAudioBuffer::read
SAMPLE read()
Definition: CircularAudioBuffer.h:71
PortAudioDeviceDriverSettings::wantWrite
bool wantWrite
Definition: PortAudioDeviceDriver.h:45
PortAudioDeviceDriver::appendSound
bool appendSound(const yarp::sig::Sound &sound)
Definition: PortAudioDeviceDriver.cpp:587
yarp::os::Thread::start
bool start()
Start the new thread running.
Definition: Thread.cpp:96
DEFAULT_SAMPLE_RATE
#define DEFAULT_SAMPLE_RATE
Definition: PortAudioDeviceDriver.h:30
PortAudioDeviceDriver::getRecordingAudioBufferMaxSize
bool getRecordingAudioBufferMaxSize(yarp::dev::AudioBufferSize &size) override
Definition: PortAudioDeviceDriver.cpp:625
Time.h
streamThread::threadRelease
void threadRelease() override
Release method.
Definition: PortAudioDeviceDriver.cpp:465
streamThread::threadInit
bool threadInit() override
Initialization method.
Definition: PortAudioDeviceDriver.cpp:469
yCTrace
#define yCTrace(component,...)
Definition: LogComponent.h:88
yarp::os::Value
A single value (typically within a Bottle).
Definition: Value.h:46
yarp::os::Thread::stop
bool stop()
Stop the thread.
Definition: Thread.cpp:84
SAMPLE
short SAMPLE
Definition: PortAudioDeviceDriver.cpp:43
circularDataBuffers
Definition: PortAudioBuffer.h:28
PortAudioDeviceDriverSettings::wantRead
bool wantRead
Definition: PortAudioDeviceDriver.h:44
PortAudioDeviceDriver::RENDER_APPEND
@ RENDER_APPEND
Definition: PortAudioDeviceDriver.h:137
yarp::dev::CircularAudioBuffer::getMaxSize
yarp::dev::AudioBufferSize getMaxSize()
Definition: CircularAudioBuffer.h:82
yarp::os::Time::delay
void delay(double seconds)
Wait for a certain number of seconds.
Definition: Time.cpp:114
streamThread::something_to_record
bool something_to_record
Definition: PortAudioDeviceDriver.h:54
DeviceDriver.h
PortAudioDeviceDriver::open
bool open(yarp::os::Searchable &config) override
Open the DeviceDriver.
Definition: PortAudioDeviceDriver.cpp:213