Nsound  0.9.4
Public Types | Public Member Functions | Static Public Member Functions | Protected Attributes | Private Member Functions | Private Attributes | List of all members
Nsound::AudioBackendLibportaudio Class Reference

#include <Nsound/AudioBackendLibportaudio.h>

Inheritance diagram for Nsound::AudioBackendLibportaudio:
Inheritance graph
[legend]

Public Types

enum  State { BACKEND_NOT_INITIALIZED, BACKEND_READY, BACKEND_ERROR }
 

Public Member Functions

 AudioBackendLibportaudio (uint32 sample_rate=44100, uint32 channels=1, uint32 bits_per_sample=16)
 
 ~AudioBackendLibportaudio ()
 
AudioBackendType getBackendType ()
 
std::string getError ()
 
std::string getInfo ()
 
void initialize ()
 
void play (void *data, uint32 n_bytes)
 
void scanDevices (AudioPlayback &pb, const AudioStream &test_clip)
 
void setOption (const std::string &key, const std::string &value)
 Set Libportaudio options. More...
 
void shutdown ()
 
uint32 getBitsPerSample ()
 
uint32 getChannels ()
 
uint32 getSampleRate ()
 
State getState ()
 
std::string getStateString ()
 Returns the backend state. More...
 

Static Public Member Functions

static std::string getStateString (const AudioBackend::State &state)
 Returns the backend state string. More...
 

Protected Attributes

uint32 sample_rate_
 
uint32 channels_
 
uint32 bits_per_sample_
 
State state_
 

Private Member Functions

 AudioBackendLibportaudio (const AudioBackendLibportaudio &copy)
 
AudioBackendLibportaudiooperator= (const AudioBackendLibportaudio &rhs)
 

Private Attributes

std::vector< std::string > options_
 
std::stringstream error_buffer_
 
PaStreamParametersout_params_
 
PaStreamstream_
 
uint32 n_frames_per_buffer_
 
uint32 driver_id_
 

Detailed Description

Definition at line 51 of file AudioBackendLibportaudio.h.

Member Enumeration Documentation

Enumerator
BACKEND_NOT_INITIALIZED 
BACKEND_READY 
BACKEND_ERROR 

Definition at line 52 of file AudioBackend.h.

Constructor & Destructor Documentation

AudioBackendLibportaudio::AudioBackendLibportaudio ( uint32  sample_rate = 44100,
uint32  channels = 1,
uint32  bits_per_sample = 16 
)

Definition at line 79 of file AudioBackendLibportaudio.cc.

References initialize().

83  :
84  AudioBackend(sample_rate, channels, bits_per_sample),
85  options_(),
86  error_buffer_(""),
87  out_params_(NULL),
88  stream_(NULL),
89 //~ pos_(0),
91  driver_id_(0)
92 {
93  initialize();
94 };
AudioBackend(uint32 sample_rate=44100, uint32 channels=1, uint32 bits_per_sample=16)
Definition: AudioBackend.h:59
AudioBackendLibportaudio::~AudioBackendLibportaudio ( )
Nsound::AudioBackendLibportaudio::AudioBackendLibportaudio ( const AudioBackendLibportaudio copy)
inlineprivate

Definition at line 113 of file AudioBackendLibportaudio.h.

114  :
115  AudioBackend(),
116  options_(),
117  error_buffer_(""),
118  out_params_(NULL),
119  stream_(NULL),
120 //~ pos_(0),
122  driver_id_(0){};
AudioBackend(uint32 sample_rate=44100, uint32 channels=1, uint32 bits_per_sample=16)
Definition: AudioBackend.h:59

Member Function Documentation

AudioBackendType AudioBackendLibportaudio::getBackendType ( )
virtual
std::string AudioBackendLibportaudio::getError ( )
virtual

Implements Nsound::AudioBackend.

Definition at line 116 of file AudioBackendLibportaudio.cc.

References error_buffer_.

Referenced by getInfo().

117 {
118  return error_buffer_.str();
119 }
std::string AudioBackendLibportaudio::getInfo ( )
virtual

Implements Nsound::AudioBackend.

Definition at line 124 of file AudioBackendLibportaudio.cc.

References Nsound::AudioBackend::BACKEND_ERROR, Nsound::AudioBackend::BACKEND_NOT_INITIALIZED, getError(), M_THROW, out_params_, and Nsound::AudioBackend::state_.

125 {
126  #ifndef NSOUND_LIBPORTAUDIO
128  M_THROW("Nsound::AudioBackendLibportaudio::getInfo():"
129  << ": Nsound was not compiled with libportaudio support.\n");
130  return;
131  #else
133  {
134  M_THROW("Nsound::AudioBackendLibportaudio::getInfo():"
135  << ": backend not initialized yet\n");
136  return "";
137  }
138  else if(state_ == BACKEND_ERROR)
139  {
140  return getError();
141  }
142 
143  const PaDeviceInfo * info = NULL;
144 
145  info = Pa_GetDeviceInfo(out_params_->device);
146 
147  if(info == NULL)
148  {
149  M_THROW("Nsound::AudioBackendLibportaudio::getInfo():"
150  << ": Pa_GetDeviceInfo() failed\n");
151 
152  return "";
153  }
154 
155  std::stringstream ss;
156 
157  ss << "libportaudio Default Driver Info:" << endl
158  << " deviceCount: " << Pa_GetDeviceCount() << endl
159  << " structVersion: " << info->structVersion << endl
160  << " name: " << info->name << endl
161  << " hostApi(index): " << info->hostApi << endl
162  << " maxInputChannels: " << info->maxInputChannels << endl
163  << " maxOutputChannels: " << info->maxOutputChannels << endl
164  << " defaultLowInputLatency: " << info->defaultLowInputLatency << endl
165  << " defaultHighInputLatency: " << info->defaultHighInputLatency << endl
166  << " defaultLowOutputLatency: " << info->defaultLowOutputLatency << endl
167  << " defaultHighOutputLatency: " << info->defaultHighOutputLatency << endl
168  << " defaultSampleRate: " << info->defaultSampleRate << endl;
169 
170  const PaHostApiInfo * api_info = NULL;
171 
172  api_info = Pa_GetHostApiInfo(info->hostApi);
173 
174  if(info == NULL)
175  {
176  M_THROW("Nsound::AudioBackendLibportaudio::getInfo():"
177  << ": Pa_GetHostApiInfo() failed\n");
178  return ss.str();
179  }
180 
181  ss << "libportaudio Default Host API Info:" << endl
182  << " structVersion: " << api_info->structVersion << endl
183  << " name: " << api_info->name << endl
184  << " deviceCount: " << api_info->deviceCount << endl
185  << " defaultInputDevice: " << api_info->defaultInputDevice << endl
186  << " defaultOutputDevice: " << api_info->defaultOutputDevice << endl;
187 
188  return ss.str();
189  #endif
190 }
#define M_THROW(message)
Definition: Macros.h:108
void AudioBackendLibportaudio::initialize ( )
virtual

Implements Nsound::AudioBackend.

Definition at line 194 of file AudioBackendLibportaudio.cc.

References Nsound::AudioBackend::BACKEND_ERROR, Nsound::AudioBackend::BACKEND_NOT_INITIALIZED, Nsound::AudioBackend::BACKEND_READY, Nsound::AudioBackend::bits_per_sample_, Nsound::AudioBackend::channels_, error_buffer_, M_THROW, n_frames_per_buffer_, out_params_, Nsound::AudioBackend::sample_rate_, Nsound::AudioBackend::state_, and stream_.

Referenced by AudioBackendLibportaudio(), and scanDevices().

195 {
196  #ifndef NSOUND_LIBPORTAUDIO
198  M_THROW("Nsound::AudioBackendLibportaudio::getInfo():"
199  << ": Nsound was not compiled with libportaudio support.\n");
200  return;
201  #else
202 
204  {
205  return;
206  }
207 
208  std::stringstream ss;
209 
210  PaError ecode = Pa_Initialize();
211 
212  if(ecode != paNoError)
213  {
215  << "Nsound::AudioBackendLibportaudio::initialize():"
216  << __LINE__
217  << ": Pa_Initialize() failed"
218  << endl
219  << Pa_GetErrorText(ecode)
220  << endl;
221 
223  return;
224  }
225 
226  // Alocate params object
228 
229  if(out_params_ == NULL)
230  {
232  << "Nsound::AudioBackendLibportaudio::initialize():"
233  << __LINE__
234  << ": failed to allocate output params struct."
235  << endl;
236 
238 
239  Pa_Terminate();
240  return;
241  }
242 
243  // Get the default ouput device
244  out_params_->device = Pa_GetDefaultOutputDevice();
245 
246  if(out_params_->device == paNoDevice)
247  {
249  << "Nsound::AudioBackendLibportaudio::initialize():"
250  << __LINE__
251  << ": Pa_GetDefaultOutputDevice() failed"
252  << endl;
253 
255 
256  Pa_Terminate();
257 
258  delete out_params_;
259  out_params_ = NULL;
260 
261  return;
262  }
263 
264  out_params_->channelCount = channels_;
265 
266  switch(bits_per_sample_)
267  {
268  case 8:
269  out_params_->sampleFormat = paInt8;
270  break;
271 
272  case 16:
273  out_params_->sampleFormat = paInt16;
274  break;
275 
276  case 32:
277  out_params_->sampleFormat = paInt32;
278  break;
279 
280  default:
282  << "Nsound::AudioBackendLibportaudio::initialize():"
283  << __LINE__
284  << ": can't handle " << bits_per_sample_
285  << " bits per sample"
286  << endl;
287 
289 
290  Pa_Terminate();
291 
292  delete out_params_;
293  out_params_ = NULL;
294 
295  return;
296  }
297 
298  out_params_->suggestedLatency =
299  Pa_GetDeviceInfo(out_params_->device)->defaultHighOutputLatency;
300 
301  out_params_->hostApiSpecificStreamInfo = NULL;
302 
303  // Open the stream.
304  ecode = Pa_OpenStream(
305  & stream_,
306  NULL, // no input channel
307  out_params_,
308  static_cast<double>(sample_rate_),
310  paClipOff,
311  NULL, // no callback for now
312  NULL);
313 
314  if(ecode != paNoError)
315  {
317  << "Nsound::AudioBackendLibportaudio::initialize():"
318  << __LINE__
319  << ": Pa_OpenStream() failed"
320  << endl
321  << Pa_GetErrorText(ecode)
322  << endl;
323 
325 
326  Pa_Terminate();
327 
328  delete out_params_;
329  out_params_ = NULL;
330 
331  return;
332  }
333 
335  #endif
336 }
#define M_THROW(message)
Definition: Macros.h:108
void AudioBackendLibportaudio::play ( void *  data,
uint32  n_bytes 
)
virtual

Implements Nsound::AudioBackend.

Definition at line 389 of file AudioBackendLibportaudio.cc.

References Nsound::AudioBackend::BACKEND_ERROR, Nsound::AudioBackend::BACKEND_READY, error_buffer_, M_THROW, n_frames_per_buffer_, out_params_, Nsound::AudioBackend::state_, stream_, and write_stream().

390 {
391  #ifndef NSOUND_LIBPORTAUDIO
393  M_THROW("Nsound::AudioBackendLibportaudio::getInfo():"
394  << ": Nsound was not compiled with libportaudio support.\n");
395  return;
396  #else
397 
398  if(state_ != BACKEND_READY)
399  {
400  return;
401  }
402 
403  if(n_bytes == 0)
404  {
405  return;
406  }
407 
408  if(data == NULL)
409  {
411  << "Nsound::AudioBackendLibportaudio::play():"
412  << __LINE__
413  << ": data is NULL"
414  << endl;
415 
417 
418  return;
419  }
420 
421  // Start the stream
422  PaError ecode = Pa_StartStream(stream_);
423 
424  if(ecode != paNoError)
425  {
427  << "Nsound::AudioBackendLibportaudio::play():"
428  << __LINE__
429  << ": Pa_StartStream() failed"
430  << endl
431  << Pa_GetErrorText(ecode)
432  << endl;
433 
435 
436  Pa_CloseStream(stream_);
437  Pa_Terminate();
438 
439  delete out_params_;
440  out_params_ = NULL;
441 
442  return;
443  }
444 
445  uint32 bits = 0;
446 
447  switch(out_params_->sampleFormat)
448  {
449  case paInt8:
450  bits = 8;
451  break;
452 
453  case paInt16:
454  bits = 16;
455  break;
456 
457  case paInt32:
458  bits = 32;
459  break;
460 
461  default:
463  << "Nsound::AudioBackendLibportaudio::initialize():"
464  << __LINE__
465  << ": can't handle bits per sample type: "
466  << out_params_->sampleFormat
467  << endl;
468 
470 
471  Pa_CloseStream(stream_);
472  Pa_Terminate();
473 
474  delete out_params_;
475  out_params_ = NULL;
476 
477  return;
478  }
479 
480  // Calculate the number of samples.
481  uint32 n_channels = out_params_->channelCount;
482  uint32 bytes_per_sample = bits / 8;
483  uint32 n_samples = n_bytes / bytes_per_sample / n_channels;
484 
485  uint32 i = 0;
486  for(
487  i = 0;
488  i < n_samples - n_frames_per_buffer_;
490  {
491  ecode = write_stream(
492  stream_,
493  data,
494  i * n_channels,
495  n_frames_per_buffer_,
496  out_params_->sampleFormat);
497 
498  if(ecode != paNoError)
499  {
501  << "Nsound::AudioBackendLibportaudio::play():"
502  << __LINE__
503  << ": Pa_WriteStream() failed"
504  << endl
505  << Pa_GetErrorText(ecode)
506  << endl;
507 
509 
510  Pa_StopStream(stream_);
511  Pa_CloseStream(stream_);
512  Pa_Terminate();
513 
514  delete out_params_;
515  out_params_ = NULL;
516 
517  return;
518  }
519  }
520 
521  // Write out remaining samples
522  ecode = write_stream(
523  stream_,
524  data,
525  i,
526  n_samples - i,
527  out_params_->sampleFormat);
528 
529  if(ecode != paNoError)
530  {
532  << "Nsound::AudioBackendLibportaudio::play():"
533  << __LINE__
534  << ": Pa_WriteStream() failed"
535  << endl
536  << Pa_GetErrorText(ecode)
537  << endl;
538 
540 
541  Pa_StopStream(stream_);
542  Pa_CloseStream(stream_);
543  Pa_Terminate();
544 
545  delete out_params_;
546  out_params_ = NULL;
547 
548  return;
549  }
550 
551  // Wait 500 ms to allow the stream to finish playing.
552  //
553  // At least on my box the playback is always cut off, especially when
554  // using Audacity, it's playback is cut off, perhaps this is releated
555  // to the audio driver. I'll leave this in for now.
556  //
557 
558  // POSIX only implementation
559  #if defined(NSOUND_PLATFORM_OS_LINUX)
560  timespec wait_time;
561  wait_time.tv_sec = 0;
562  wait_time.tv_nsec = 500000000;
563 
564  nanosleep(&wait_time, NULL);
565  #endif
566 
567  // Stop the stream
568  ecode = Pa_StopStream(stream_);
569 
570  if(ecode != paNoError)
571  {
573  << "Nsound::AudioBackendLibportaudio::play():"
574  << __LINE__
575  << ": Pa_StopStream() failed"
576  << endl
577  << Pa_GetErrorText(ecode)
578  << endl;
579 
581 
582  Pa_CloseStream(stream_);
583  Pa_Terminate();
584 
585  delete out_params_;
586  out_params_ = NULL;
587 
588  return;
589  }
590 
591  #endif
592 }
unsigned int uint32
Definition: Nsound.h:153
PaError write_stream(PaStream *stream, void *data, uint32 position, uint32 n_frames_per_buffer, PaSampleFormat format)
#define M_THROW(message)
Definition: Macros.h:108
void AudioBackendLibportaudio::scanDevices ( AudioPlayback pb,
const AudioStream test_clip 
)
virtual

Implements Nsound::AudioBackend.

Definition at line 606 of file AudioBackendLibportaudio.cc.

References driver_id_, initialize(), lower(), Nsound::AudioPlayback::play(), and shutdown().

607 {
608  uint32 orig_driver_id = driver_id_;
609 
610  uint32 n_host_apis = Pa_GetHostApiCount();
611 
612  for(uint32 i = 0; i < n_host_apis; ++i)
613  {
614  const PaHostApiInfo * info = Pa_GetHostApiInfo(i);
615 
616  if(info != NULL)
617  {
618  std::string short_name = lower(std::string(info->name));
619 
620  cout
621  << "Libportaudio: found driver '"
622  << short_name
623  << "', id = "
624  << i
625  << ", deviceCount = "
626  << info->deviceCount
627  << ", defaultOutputDevice = "
628  << info->defaultOutputDevice
629  << "\nPLAYBACK STARTING ...";
630  cout.flush();
631 
632  shutdown();
633 
634  driver_id_ = i;
635 
636  initialize();
637 
638  pb.play(test_clip);
639 
640  cout << " STOPPED\n";
641  cout.flush();
642  }
643  }
644 
645  shutdown();
646  driver_id_ = orig_driver_id;
647 }
unsigned int uint32
Definition: Nsound.h:153
static std::string lower(const std::string &x)
void play(const AudioStream &a)
Plays the AudioStream throuh the backend.
void AudioBackendLibportaudio::setOption ( const std::string &  key,
const std::string &  value 
)
virtual

Set Libportaudio options.

Available options:

Key Value
"driver" "alsa", "oss", "asihpi", "jack", "coreaudio", "asio", "wasapi", "wdm/ks", "directsound", "wmme"
"frames_per_buffer" integer, default = 64

Implements Nsound::AudioBackend.

Definition at line 674 of file AudioBackendLibportaudio.cc.

References Nsound::AudioBackend::BACKEND_ERROR, driver_id_, integer(), lower(), M_THROW, n_frames_per_buffer_, and Nsound::AudioBackend::state_.

675 {
676  #ifndef NSOUND_LIBPORTAUDIO
678  M_THROW("Nsound::AudioBackendLibportaudio::getInfo():"
679  << ": Nsound was not compiled with libportaudio support.\n");
680  return;
681  #else
682 
683  std::string k = lower(key);
684 
685  if(k == "frames_per_buffer")
686  {
687  int32 i = integer(value, &state_);
688 
689  if(i >= 1)
690  {
692  }
693  }
694  else
695  if(k == "driver")
696  {
697  std::string driver_name = lower(value);
698 
699  uint32 n_host_apis = Pa_GetHostApiCount();
700 
701  bool found_driver = false;
702 
703  for(uint32 i = 0; i < n_host_apis; ++i)
704  {
705  const PaHostApiInfo * info = Pa_GetHostApiInfo(i);
706 
707  if(info != NULL)
708  {
709  std::string short_name = lower(std::string(info->name));
710 
711  if(driver_name == short_name)
712  {
713  driver_id_ = i;
714  found_driver = true;
715  }
716  }
717  }
718 
719  if(!found_driver)
720  {
722  M_THROW("Nsound::AudioBackendLibportaudio::setOption():"
723  << ": failed to select driver '"
724  << key
725  << "'\n");
726  return;
727  }
728  }
729  else
730  {
732  M_THROW("Nsound::AudioBackendLibportaudio::setOption():"
733  << ": unrecognized key '"
734  << key
735  << "'\n");
736  return;
737  }
738 
739  #endif
740 }
unsigned int uint32
Definition: Nsound.h:153
static std::string lower(const std::string &x)
static int32 integer(const std::string &x, Nsound::AudioBackend::State *state)
#define M_THROW(message)
Definition: Macros.h:108
signed int int32
Definition: Nsound.h:142
void AudioBackendLibportaudio::shutdown ( )
virtual

Implements Nsound::AudioBackend.

Definition at line 744 of file AudioBackendLibportaudio.cc.

References Nsound::AudioBackend::BACKEND_ERROR, Nsound::AudioBackend::BACKEND_NOT_INITIALIZED, M_THROW, out_params_, Nsound::AudioBackend::state_, and stream_.

Referenced by scanDevices(), and ~AudioBackendLibportaudio().

745 {
746  #ifndef NSOUND_LIBPORTAUDIO
748  M_THROW("Nsound::AudioBackendLibportaudio::getInfo():"
749  << ": Nsound was not compiled with libportaudio support.\n");
750  return;
751  #else
752 
753  if(stream_ != NULL)
754  {
755  Pa_CloseStream(stream_);
756  Pa_Terminate();
757 
758  stream_ = NULL;
759 
760  delete out_params_;
761  out_params_ = NULL;
762  }
763 
765 
766  #endif
767 }
#define M_THROW(message)
Definition: Macros.h:108
AudioBackendLibportaudio& Nsound::AudioBackendLibportaudio::operator= ( const AudioBackendLibportaudio rhs)
inlineprivate

Definition at line 124 of file AudioBackendLibportaudio.h.

125  {return *this;};
uint32 Nsound::AudioBackend::getBitsPerSample ( )
inlineinherited

Definition at line 77 of file AudioBackend.h.

References Nsound::AudioBackend::bits_per_sample_.

Referenced by Nsound::AudioPlayback::getBitsPerSample().

77 {return bits_per_sample_;};
uint32 Nsound::AudioBackend::getChannels ( )
inlineinherited

Definition at line 80 of file AudioBackend.h.

References Nsound::AudioBackend::channels_.

Referenced by Nsound::AudioPlayback::getChannels(), and play_int().

80 {return channels_;};
uint32 Nsound::AudioBackend::getSampleRate ( )
inlineinherited

Definition at line 91 of file AudioBackend.h.

References Nsound::AudioBackend::sample_rate_.

Referenced by Nsound::AudioPlayback::getSampleRate().

91 {return sample_rate_;};
State Nsound::AudioBackend::getState ( )
inlineinherited
std::string AudioBackend::getStateString ( )
inherited

Returns the backend state.

Definition at line 43 of file AudioBackend.cc.

References Nsound::AudioBackend::state_, and state_strings.

Referenced by Nsound::AudioPlayback::getStateString().

44 {
45  return state_strings[state_];
46 }
std::string state_strings[3]
Definition: AudioBackend.cc:33
std::string AudioBackend::getStateString ( const AudioBackend::State state)
staticinherited

Returns the backend state string.

Definition at line 51 of file AudioBackend.cc.

References Nsound::AudioBackend::BACKEND_ERROR, Nsound::AudioBackend::BACKEND_NOT_INITIALIZED, and state_strings.

52 {
53  if( state >= BACKEND_NOT_INITIALIZED &&
54  state <= BACKEND_ERROR)
55  {
56  return state_strings[state];
57  }
58 
59  return "Unknown Backend State";
60 }
std::string state_strings[3]
Definition: AudioBackend.cc:33

Member Data Documentation

std::vector< std::string > Nsound::AudioBackendLibportaudio::options_
private

Definition at line 125 of file AudioBackendLibportaudio.h.

std::stringstream Nsound::AudioBackendLibportaudio::error_buffer_
private

Definition at line 129 of file AudioBackendLibportaudio.h.

Referenced by getError(), initialize(), and play().

PaStreamParameters* Nsound::AudioBackendLibportaudio::out_params_
private

Definition at line 131 of file AudioBackendLibportaudio.h.

Referenced by getInfo(), initialize(), play(), and shutdown().

PaStream* Nsound::AudioBackendLibportaudio::stream_
private

Definition at line 132 of file AudioBackendLibportaudio.h.

Referenced by initialize(), play(), and shutdown().

uint32 Nsound::AudioBackendLibportaudio::n_frames_per_buffer_
private

Definition at line 136 of file AudioBackendLibportaudio.h.

Referenced by initialize(), play(), and setOption().

uint32 Nsound::AudioBackendLibportaudio::driver_id_
private

Definition at line 138 of file AudioBackendLibportaudio.h.

Referenced by scanDevices(), and setOption().

uint32 Nsound::AudioBackend::sample_rate_
protectedinherited
uint32 Nsound::AudioBackend::channels_
protectedinherited
uint32 Nsound::AudioBackend::bits_per_sample_
protectedinherited
State Nsound::AudioBackend::state_
protectedinherited

The documentation for this class was generated from the following files: