NAP
portaudioservice.h
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4 
5 #pragma once
6 
7 // Audio includes
8 #include <audio/service/audioservice.h>
9 #include <audio/utility/safeptr.h>
10 
11 // Nap includes
12 #include <nap/service.h>
13 #include <utility/threading.h>
14 
15 // third party includes
16 #include <portaudio.h>
17 
18 
19 namespace nap
20 {
21  namespace audio
22  {
23 
24  // Forward declarations
25  class PortAudioService;
26 
31  {
32  RTTI_ENABLE(ServiceConfiguration)
33  public:
34  virtual rtti::TypeInfo getServiceType() const { return RTTI_OF(PortAudioService); }
35 
39  struct NAPAPI DeviceSettings
40  {
46  std::string mHostApi = "";
47 
52  std::string mInputDevice = "";
53 
58  std::string mOutputDevice = "";
59 
64  int mInputChannelCount = 1;
65 
70  int mOutputChannelCount = 2;
71 
75  bool mDisableInput = false;
76 
80  bool mDisableOutput = false;
81 
85  float mSampleRate = 44100;
86 
90  int mBufferSize = 1024;
91 
97  int mInternalBufferSize = 1024;
98  };
99 
104 
109  bool mAllowChannelCountFailure = true;
110 
114  bool mAllowDeviceFailure = true;
115  };
116 
121  class NAPAPI PortAudioService final : public Service
122  {
123  RTTI_ENABLE(nap::Service)
124 
125  public:
126  PortAudioService(ServiceConfiguration* configuration);
127 
128  ~PortAudioService() = default;
129 
133  void registerObjectCreators(rtti::Factory& factory) override;
134 
138  bool init(nap::utility::ErrorState& errorState) override;
139 
143  void shutdown() override;
144 
148  void preShutdown() override;
149 
153  NodeManager& getNodeManager() { return mAudioService->getNodeManager(); }
154 
158  bool getAllowChannelCountFailure() { return getConfiguration<PortAudioServiceConfiguration>()->mAllowChannelCountFailure; }
159 
163  unsigned int getHostApiCount();
164 
170  const PaHostApiInfo& getHostApiInfo(unsigned int hostApiIndex);
171 
175  std::vector<const PaHostApiInfo*> getHostApis();
176 
180  std::string getHostApiName(unsigned int hostApiIndex);
181 
186  unsigned int getDeviceCount(unsigned int hostApiIndex);
187 
194  const PaDeviceInfo& getDeviceInfo(unsigned int hostApiIndex, unsigned int localDeviceIndex);
195 
201  const PaDeviceInfo& getDeviceInfo(unsigned int deviceIndex);
202 
208  std::vector<const PaDeviceInfo*> getDevices(unsigned int hostApiIndex);
209 
213  void printDevices();
214 
220  std::string getDeviceName(unsigned int hostApiIndex, unsigned int localDeviceIndex);
221 
230  int getInputDeviceIndex(int hostApiIndex, const std::string& device);
231 
240  int getOutputDeviceIndex(int hostApiIndex, const std::string& device);
241 
246  int getDeviceIndex(int hostApiIndex, int hostApiDeviceIndex);
247 
254  int getHostApiIndex(const std::string& hostApi);
255 
259  int getCurrentHostApiIndex() const { return mHostApiIndex; }
260 
264  int getCurrentInputDeviceIndex() const { return mInputDeviceIndex; }
265 
269  int getCurrentOutputDeviceIndex() const { return mOutputDeviceIndex; }
270 
274  int getCurrentBufferSize() const { return getConfiguration<PortAudioServiceConfiguration>()->mDeviceSettings.mBufferSize; }
275 
283  bool openStream(const PortAudioServiceConfiguration::DeviceSettings& settings, utility::ErrorState& errorState);
284 
289  const PortAudioServiceConfiguration::DeviceSettings& getDeviceSettings() const;
290 
295  bool closeStream(utility::ErrorState& errorState);
296 
302  bool start(utility::ErrorState& errorState);
303 
309  bool stop(utility::ErrorState& errorState);
310 
314  bool isOpened() { return mStream != nullptr; }
315 
319  bool isActive();
320 
324  const std::string& getErrorMessage() const { return mErrorMessage; }
325 
326  private:
334  bool _openStream(const PortAudioServiceConfiguration::DeviceSettings& settings, utility::ErrorState& errorState);
335 
340  bool openStream(utility::ErrorState& errorState);
341 
342  /*
343  * Verifies if the ammounts of input and output channels specified in the configuration are supported on the given devices. If so, @inputDeviceIndex and @outputDeviceIndex will be set to these. If not and @mAllowChannelCountFailure is set to true, it will return the maximum numbers of channels of the selected devices instead. If @mAllowChannelCountFailure is false initialization will fail.
344  */
345  bool checkChannelCounts(int inputDeviceIndex, int outputDeviceIndex, int& inputChannelCount,
346  int& outputChannelCount, utility::ErrorState& errorState);
347 
348  private:
349  PaStream* mStream = nullptr; // Pointer to the stream managed by portaudio.
350  int mHostApiIndex = -1; // The actual host Api being used.
351  int mInputDeviceIndex = -1; // The actual input device being used, if any.
352  int mOutputDeviceIndex = -1; // The actual output device being used, if any.
353  bool mPortAudioInitialized = false; // If port audio is initialized
354  bool mMpg123Initialized = false; // If mpg123 is initialized
355 
356  std::string mErrorMessage = ""; // Holds the error message if public openStream() method was called unsuccesfully.
357 
358  audio::AudioService* mAudioService = nullptr;
359  };
360  }
361 }
nap::audio::PortAudioServiceConfiguration::getServiceType
virtual rtti::TypeInfo getServiceType() const
Definition: portaudioservice.h:34
nap::audio::PortAudioService::getAllowChannelCountFailure
bool getAllowChannelCountFailure()
Definition: portaudioservice.h:158
nap::audio::PortAudioService::getCurrentOutputDeviceIndex
int getCurrentOutputDeviceIndex() const
Definition: portaudioservice.h:269
nap::audio::PortAudioServiceConfiguration::mDeviceSettings
DeviceSettings mDeviceSettings
Definition: portaudioservice.h:103
nap::audio::PortAudioService::getCurrentHostApiIndex
int getCurrentHostApiIndex() const
Definition: portaudioservice.h:259
nap::utility::ErrorState
Definition: errorstate.h:19
nap::audio::PortAudioService::getCurrentBufferSize
int getCurrentBufferSize() const
Definition: portaudioservice.h:274
nap::ServiceConfiguration
Definition: service.h:28
nap::audio::PortAudioServiceConfiguration
Definition: portaudioservice.h:30
nap::audio::AudioService
Definition: audioservice.h:26
nap::audio::NodeManager
Definition: audionodemanager.h:33
nap::Service
Definition: templateservice.h:8
nap::audio::PortAudioService::getCurrentInputDeviceIndex
int getCurrentInputDeviceIndex() const
Definition: portaudioservice.h:264
nap::rtti::Factory
Definition: factory.h:78
nap::audio::PortAudioServiceConfiguration::DeviceSettings
Definition: portaudioservice.h:39
nap::audio::PortAudioService::isOpened
bool isOpened()
Definition: portaudioservice.h:314
nap
Definition: templateapp.h:17
nap::rtti::TypeInfo
rttr::type TypeInfo
Definition: typeinfo.h:140
nap::audio::PortAudioService
Definition: portaudioservice.h:121
nap::audio::PortAudioService::getNodeManager
NodeManager & getNodeManager()
Definition: portaudioservice.h:153
nap::audio::PortAudioService::getErrorMessage
const std::string & getErrorMessage() const
Definition: portaudioservice.h:324