1 /* 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef AUDIO_SERVICE_CLIENT_H 17 #define AUDIO_SERVICE_CLIENT_H 18 19 #include <algorithm> 20 #include <array> 21 #include <cstring> 22 #include <iostream> 23 #include <map> 24 #include <memory> 25 #include <mutex> 26 #include <queue> 27 #include <stdlib.h> 28 #include <thread> 29 #include <unistd.h> 30 #include <pulse/pulseaudio.h> 31 #include <pulse/thread-mainloop.h> 32 #include <audio_error.h> 33 #include <audio_info.h> 34 #include <audio_timer.h> 35 36 #include "audio_capturer.h" 37 #include "audio_renderer.h" 38 #include "audio_system_manager.h" 39 40 namespace OHOS { 41 namespace AudioStandard { 42 enum ASClientType { 43 AUDIO_SERVICE_CLIENT_PLAYBACK, 44 AUDIO_SERVICE_CLIENT_RECORD, 45 AUDIO_SERVICE_CLIENT_CONTROLLER 46 }; 47 48 typedef pa_sink_input_info SinkInputInfo; 49 typedef pa_source_output_info SourceOutputInfo; 50 typedef pa_sink_info SinkDeviceInfo; 51 typedef pa_source_info SourceDeviceInfo; 52 typedef pa_client_info ClientInfo; 53 54 struct StreamBuffer { 55 uint8_t *buffer; // the virtual address of stream 56 uint32_t bufferLen; // stream length in bytes 57 }; 58 59 struct AudioCache { 60 std::unique_ptr<uint8_t[]> buffer; 61 uint32_t readIndex; 62 uint32_t writeIndex; 63 uint32_t totalCacheSize; 64 bool isFull; 65 }; 66 67 /** 68 * @brief Enumerates the stream states of the current device. 69 * 70 * @since 1.0 71 * @version 1.0 72 */ 73 enum State { 74 /** INVALID */ 75 INVALID = -1, 76 /** New */ 77 NEW, 78 /** Prepared */ 79 PREPARED, 80 /** Running */ 81 RUNNING, 82 /** Stopped */ 83 STOPPED, 84 /** Released */ 85 RELEASED, 86 /** Paused */ 87 PAUSED 88 }; 89 90 class AudioStreamCallback { 91 public: 92 virtual ~AudioStreamCallback() = default; 93 /** 94 * Called when stream state is updated. 95 * 96 * @param state Indicates the InterruptEvent information needed by client. 97 * For details, refer InterruptEvent struct in audio_info.h 98 */ 99 virtual void OnStateChange(const State state) = 0; 100 }; 101 102 class AudioRendererCallbacks { 103 public: 104 virtual ~AudioRendererCallbacks(); 105 virtual void OnSinkDeviceUpdatedCb() const = 0; 106 // Need to check required state changes to update applications 107 virtual void OnStreamStateChangeCb() const = 0; 108 virtual void OnStreamBufferUnderFlowCb() const = 0; 109 virtual void OnStreamBufferOverFlowCb() const = 0; 110 virtual void OnErrorCb(AudioServiceErrorCodes error) const = 0; 111 virtual void OnEventCb(AudioServiceEventTypes error) const = 0; 112 }; 113 114 class AudioCapturerCallbacks { 115 public: 116 virtual ~AudioCapturerCallbacks(); 117 virtual void OnSourceDeviceUpdatedCb() const = 0; 118 // Need to check required state changes to update applications 119 virtual void OnStreamStateChangeCb() const = 0; 120 virtual void OnStreamBufferUnderFlowCb() const = 0; 121 virtual void OnStreamBufferOverFlowCb() const = 0; 122 virtual void OnErrorCb(AudioServiceErrorCodes error) const = 0; 123 virtual void OnEventCb(AudioServiceEventTypes error) const = 0; 124 }; 125 126 class AudioServiceClient : public AudioTimer { 127 public: 128 static constexpr char PA_RUNTIME_DIR[] = "/data/data/.pulse_dir/runtime"; 129 static constexpr char PA_STATE_DIR[] = "/data/data/.pulse_dir/state"; 130 static constexpr char PA_HOME_DIR[] = "/data/data/.pulse_dir/state"; 131 132 AudioServiceClient(); 133 virtual ~AudioServiceClient(); 134 135 /** 136 * Initializes audio service client for the required client type 137 * 138 * @param eClientType indicates the client type like playback, record or controller. 139 * @return Returns {@code 0} if success; returns {@code -1} otherwise. 140 */ 141 int32_t Initialize(ASClientType eClientType); 142 143 // Stream handling APIs 144 145 /** 146 * Creates & initializes resources based on the audioParams and audioType 147 * 148 * @param audioParams indicate format, sampling rate and number of channels 149 * @param audioType indicate the stream type like music, system, ringtone etc 150 * @return Returns {@code 0} if success; returns {@code -1} otherwise. 151 */ 152 int32_t CreateStream(AudioStreamParams audioParams, AudioStreamType audioType); 153 154 /** 155 * @brief Obtains session ID . 156 * 157 * @return Returns unique session ID for the created session 158 */ 159 int32_t GetSessionID(uint32_t &sessionID) const; 160 161 /** 162 * Starts the stream created using CreateStream 163 * 164 * @return Returns {@code 0} if success; returns {@code -1} otherwise. 165 */ 166 int32_t StartStream(); 167 168 /** 169 * Stops the stream created using CreateStream 170 * 171 * @return Returns {@code 0} if success; returns {@code -1} otherwise. 172 */ 173 int32_t StopStream(); 174 175 /** 176 * Flushes the stream created using CreateStream. This is applicable for 177 * playback only 178 * 179 * @return Returns {@code 0} if success; returns {@code -1} otherwise. 180 */ 181 int32_t FlushStream(); 182 183 /** 184 * Drains the stream created using CreateStream. This is applicable for 185 * playback only 186 * 187 * @return Returns {@code 0} if success; returns {@code -1} otherwise. 188 */ 189 int32_t DrainStream(); 190 191 /** 192 * Pauses the stream 193 * 194 * @return Returns {@code 0} if success; returns {@code -1} otherwise. 195 */ 196 int32_t PauseStream(); 197 198 /** 199 * Update the stream type 200 * 201 * @param audioStreamType Audio stream type 202 * @return Returns {@code 0} if success; returns {@code -1} otherwise. 203 */ 204 int32_t SetStreamType(AudioStreamType audioStreamType); 205 206 /** 207 * Sets the volume of the stream associated with session ID 208 * 209 * @param sessionID indicates the ID for the active stream to be controlled 210 * @param volume indicates volume level between 0 to 65536 211 * @return Returns {@code 0} if success; returns {@code -1} otherwise. 212 */ 213 int32_t SetStreamVolume(uint32_t sessionID, uint32_t volume); 214 215 /** 216 * Get the volume of the stream associated with session ID 217 * 218 * @param sessionID indicates the ID for the active stream to be controlled 219 * @return returns volume level between 0 to 65536 220 */ 221 uint32_t GetStreamVolume(uint32_t sessionID); 222 223 /** 224 * Writes audio data of the stream created using CreateStream to active sink device 225 * 226 * @param buffer contains audio data to write 227 * @param bufferSize indicates the size of audio data in bytes to write from the buffer 228 * @param pError indicates pointer to error which will be filled in case of internal errors 229 * @return returns size of audio data written in bytes. 230 */ 231 size_t WriteStream(const StreamBuffer &stream, int32_t &pError); 232 233 /** 234 * Writes audio data of the stream created using CreateStream to active sink device 235 Used when render mode is RENDER_MODE_CALLBACK 236 * 237 * @param buffer contains audio data to write 238 * @param bufferSize indicates the size of audio data in bytes to write from the buffer 239 * @param pError indicates pointer to error which will be filled in case of internal errors 240 * @return returns size of audio data written in bytes. 241 */ 242 size_t WriteStreamInCb(const StreamBuffer &stream, int32_t &pError); 243 244 /** 245 * Reads audio data of the stream created using CreateStream from active source device 246 * 247 * @param StreamBuffer including buffer to be filled with audio data 248 * and bufferSize indicating the size of audio data to read into buffer 249 * @param isBlocking indicates if the read is blocking or not 250 * @return Returns size read if success; returns {@code -1} failure. 251 */ 252 int32_t ReadStream(StreamBuffer &stream, bool isBlocking); 253 254 /** 255 * Release the resources allocated using CreateStream 256 * 257 * @return Returns {@code 0} if success; returns {@code -1} otherwise. 258 */ 259 int32_t ReleaseStream(); 260 261 /** 262 * Provides the current timestamp for playback/record stream created using CreateStream 263 * 264 * @param timeStamp will be filled up with current timestamp 265 * @return Returns {@code 0} if success; returns {@code -1} otherwise. 266 */ 267 int32_t GetCurrentTimeStamp(uint64_t &timeStamp) const; 268 269 /** 270 * Provides the current latency for playback/record stream created using CreateStream 271 * 272 * @param latency will be filled up with the current latency in microseconds 273 * @return Returns {@code 0} if success; returns {@code -1} otherwise. 274 */ 275 int32_t GetAudioLatency(uint64_t &latency) const; 276 277 /** 278 * Provides the playback/record stream parameters created using CreateStream 279 * 280 * @param audioParams will be filled up with stream audio parameters 281 * @return Returns {@code 0} if success; returns {@code -1} otherwise. 282 */ 283 int32_t GetAudioStreamParams(AudioStreamParams &audioParams) const; 284 285 /** 286 * Provides the minimum buffer size required for this audio stream 287 * created using CreateStream 288 * @param minBufferSize will be set to minimum buffer size in bytes 289 * @return Returns {@code 0} if success; returns {@code -1} otherwise. 290 */ 291 int32_t GetMinimumBufferSize(size_t &minBufferSize) const; 292 293 /** 294 * Provides the minimum frame count required for this audio stream 295 * created using CreateStream 296 * @param frameCount will be set to minimum number of frames 297 * @return Returns {@code 0} if success; returns {@code -1} otherwise. 298 */ 299 int32_t GetMinimumFrameCount(uint32_t &frameCount) const; 300 301 /** 302 * Provides the sampling rate for the active audio stream 303 * created using CreateStream 304 * 305 * @return Returns sampling rate in Hz 306 */ 307 uint32_t GetSamplingRate() const; 308 309 /** 310 * Provides the channel count for the active audio stream 311 * created using CreateStream 312 * 313 * @return Returns number of channels 314 */ 315 uint8_t GetChannelCount() const; 316 317 /** 318 * Provides the sample size for the active audio stream 319 * created using CreateStream 320 * 321 * @return Returns sample size in number of bits 322 */ 323 uint8_t GetSampleSize() const; 324 325 // Device volume & route handling APIs 326 327 // Audio stream callbacks 328 329 /** 330 * Register for callbacks associated with the playback stream created using CreateStream 331 * 332 * @param cb indicates pointer for registered callbacks 333 * @return none 334 */ 335 void RegisterAudioRendererCallbacks(const AudioRendererCallbacks &cb); 336 337 /** 338 * Register for callbacks associated with the record stream created using CreateStream 339 * 340 * @param cb indicates pointer for registered callbacks 341 * @return none 342 */ 343 void RegisterAudioCapturerCallbacks(const AudioCapturerCallbacks &cb); 344 345 /** 346 * Set the renderer frame position callback 347 * 348 * @param callback indicates pointer for registered callbacks 349 * @return none 350 */ 351 void SetRendererPositionCallback(int64_t markPosition, const std::shared_ptr<RendererPositionCallback> &callback); 352 353 /** 354 * Unset the renderer frame position callback 355 * 356 * @return none 357 */ 358 void UnsetRendererPositionCallback(); 359 360 /** 361 * Set the renderer frame period position callback 362 * 363 * @param callback indicates pointer for registered callbacks 364 * @return none 365 */ 366 void SetRendererPeriodPositionCallback(int64_t markPosition, 367 const std::shared_ptr<RendererPeriodPositionCallback> &callback); 368 369 /** 370 * Unset the renderer frame period position callback 371 * 372 * @return none 373 */ 374 void UnsetRendererPeriodPositionCallback(); 375 376 /** 377 * Set the capturer frame position callback 378 * 379 * @param callback indicates pointer for registered callbacks 380 * @return none 381 */ 382 void SetCapturerPositionCallback(int64_t markPosition, const std::shared_ptr<CapturerPositionCallback> &callback); 383 384 /** 385 * Unset the capturer frame position callback 386 * 387 * @return none 388 */ 389 void UnsetCapturerPositionCallback(); 390 391 /** 392 * Set the capturer frame period position callback 393 * 394 * @param callback indicates pointer for registered callbacks 395 * @return none 396 */ 397 void SetCapturerPeriodPositionCallback(int64_t markPosition, 398 const std::shared_ptr<CapturerPeriodPositionCallback> &callback); 399 400 /** 401 * Unset the capturer frame period position callback 402 * 403 * @return none 404 */ 405 void UnsetCapturerPeriodPositionCallback(); 406 407 /** 408 * @brief Set the track volume 409 * 410 * @param volume The volume to be set for the current track. 411 * @return Returns {@link SUCCESS} if volume is successfully set; returns an error code 412 * defined in {@link audio_errors.h} otherwise. 413 */ 414 int32_t SetStreamVolume(float volume); 415 416 /** 417 * @brief Obtains the current track volume 418 * 419 * @return Returns current track volume 420 */ 421 float GetStreamVolume(); 422 423 /** 424 * @brief Set the render rate 425 * 426 * @param renderRate The rate at which the stream needs to be rendered. 427 * @return Returns {@link SUCCESS} if render rate is successfully set; returns an error code 428 * defined in {@link audio_errors.h} otherwise. 429 */ 430 int32_t SetStreamRenderRate(AudioRendererRate renderRate); 431 432 /** 433 * @brief Obtains the current render rate 434 * 435 * @return Returns current render rate 436 */ 437 AudioRendererRate GetStreamRenderRate(); 438 439 /** 440 * @brief Set the buffer duration in msec 441 * 442 * @param bufferSizeInMsec buffer size in duration. 443 * @return Returns {@link SUCCESS} defined in {@link audio_errors.h} otherwise. 444 */ 445 int32_t SetBufferSizeInMsec(int32_t bufferSizeInMsec); 446 447 /** 448 * @brief Saves StreamCallback 449 * 450 * @param callback callback reference to be saved. 451 * @return none. 452 */ 453 454 void SaveStreamCallback(const std::weak_ptr<AudioStreamCallback> &callback); 455 456 /** 457 * @brief Sets the render mode. By default the mode is RENDER_MODE_NORMAL. 458 * This API is needs to be used only if RENDER_MODE_CALLBACK is required. 459 * 460 * * @param renderMode The mode of render. 461 * @return Returns {@link SUCCESS} if render mode is successfully set; returns an error code 462 * defined in {@link audio_errors.h} otherwise. 463 */ 464 int32_t SetAudioRenderMode(AudioRenderMode renderMode); 465 466 /** 467 * @brief Obtains the render mode. 468 * 469 * @return Returns current render mode. 470 */ 471 AudioRenderMode GetAudioRenderMode(); 472 473 /** 474 * @brief Registers the renderer write callback listener. 475 * This API should only be used if RENDER_MODE_CALLBACK is needed. 476 * 477 * @return Returns {@link SUCCESS} if callback registration is successful; returns an error code 478 * defined in {@link audio_errors.h} otherwise. 479 */ 480 int32_t SaveWriteCallback(const std::weak_ptr<AudioRendererWriteCallback> &callback); 481 482 /** 483 * @brief Set the applicationcache path to access the application resources 484 * 485 * @return none 486 */ 487 void SetApplicationCachePath(const std::string cachePath); 488 489 // Audio timer callback 490 virtual void OnTimeOut(); 491 492 private: 493 pa_threaded_mainloop *mainLoop; 494 pa_mainloop_api *api; 495 pa_context *context; 496 pa_stream *paStream; 497 pa_sample_spec sampleSpec; 498 499 std::mutex dataMutex; 500 std::mutex ctrlMutex; 501 std::mutex capturerMarkReachedMutex_; 502 std::mutex capturerPeriodReachedMutex_; 503 std::mutex rendererMarkReachedMutex_; 504 std::mutex rendererPeriodReachedMutex_; 505 506 AudioCache acache; 507 const void *internalReadBuffer; 508 size_t internalRdBufLen; 509 size_t internalRdBufIndex; 510 size_t setBufferSize; 511 int32_t streamCmdStatus; 512 int32_t streamDrainStatus; 513 int32_t streamFlushStatus; 514 bool isMainLoopStarted; 515 bool isContextConnected; 516 bool isStreamConnected; 517 518 std::string appCookiePath = ""; 519 std::string cachePath_ = ""; 520 521 float mVolumeFactor; 522 AudioStreamType mStreamType; 523 AudioSystemManager *mAudioSystemMgr; 524 525 pa_cvolume cvolume; 526 uint32_t streamIndex; 527 uint32_t volumeChannels; 528 bool streamInfoUpdated; 529 530 AudioRendererRate renderRate; 531 AudioRenderMode renderMode_; 532 std::weak_ptr<AudioRendererWriteCallback> writeCallback_; 533 534 uint32_t mFrameSize = 0; 535 bool mMarkReached = false; 536 uint64_t mFrameMarkPosition = 0; 537 uint64_t mFramePeriodNumber = 0; 538 539 uint64_t mTotalBytesWritten = 0; 540 uint64_t mFramePeriodWritten = 0; 541 std::shared_ptr<RendererPositionCallback> mRenderPositionCb; 542 std::shared_ptr<RendererPeriodPositionCallback> mRenderPeriodPositionCb; 543 544 uint64_t mTotalBytesRead = 0; 545 uint64_t mFramePeriodRead = 0; 546 std::shared_ptr<CapturerPositionCallback> mCapturePositionCb; 547 std::shared_ptr<CapturerPeriodPositionCallback> mCapturePeriodPositionCb; 548 549 std::vector<std::unique_ptr<std::thread>> mPositionCBThreads; 550 std::vector<std::unique_ptr<std::thread>> mPeriodPositionCBThreads; 551 552 std::weak_ptr<AudioStreamCallback> streamCallback_; 553 State state_; 554 pa_stream_success_cb_t PAStreamCorkSuccessCb; 555 556 // To be set while using audio stream 557 // functionality for callbacks 558 AudioRendererCallbacks *mAudioRendererCallbacks; 559 AudioCapturerCallbacks *mAudioCapturerCallbacks; 560 561 std::map<uint32_t, SinkDeviceInfo*> sinkDevices; 562 std::map<uint32_t, SourceDeviceInfo*> sourceDevices; 563 std::map<uint32_t, SinkInputInfo*> sinkInputs; 564 std::map<uint32_t, SourceOutputInfo*> sourceOutputs; 565 std::map<uint32_t, ClientInfo*> clientInfo; 566 567 ASClientType eAudioClientType; 568 569 uint32_t underFlowCount; 570 int32_t ConnectStreamToPA(); 571 572 // Audio cache related functions. These APIs are applicable only for playback scenarios 573 int32_t InitializeAudioCache(); 574 size_t WriteToAudioCache(const StreamBuffer &stream); 575 int32_t DrainAudioCache(); 576 577 int32_t UpdateReadBuffer(uint8_t *buffer, size_t &length, size_t &readSize); 578 int32_t PaWriteStream(const uint8_t *buffer, size_t &length); 579 void HandleRenderPositionCallbacks(size_t bytesWritten); 580 void HandleCapturePositionCallbacks(size_t bytesRead); 581 582 // Error code used 583 static const uint32_t AUDIO_CLIENT_SUCCESS = 0; 584 static const uint32_t AUDIO_CLIENT_ERR = -1; 585 static const uint32_t AUDIO_CLIENT_INVALID_PARAMS_ERR = -2; 586 static const uint32_t AUDIO_CLIENT_INIT_ERR = -3; 587 static const uint32_t AUDIO_CLIENT_CREATE_STREAM_ERR = -4; 588 static const uint32_t AUDIO_CLIENT_START_STREAM_ERR = -5; 589 static const uint32_t AUDIO_CLIENT_READ_STREAM_ERR = -6; 590 static const uint32_t AUDIO_CLIENT_WRITE_STREAM_ERR = -7; 591 static const uint32_t AUDIO_CLIENT_PA_ERR = -8; 592 593 // Default values 594 static const uint32_t MINIMUM_BUFFER_SIZE = 1024; 595 static const uint32_t DEFAULT_SAMPLING_RATE = 44100; 596 static const uint8_t DEFAULT_CHANNEL_COUNT = 2; 597 static const uint8_t DEFAULT_SAMPLE_SIZE = 2; 598 static const uint32_t DEFAULT_STREAM_VOLUME = 65536; 599 static const std::string GetStreamName(AudioStreamType audioType); 600 static pa_sample_spec ConvertToPAAudioParams(AudioStreamParams audioParams); 601 static AudioStreamParams ConvertFromPAAudioParams(pa_sample_spec paSampleSpec); 602 603 static constexpr float MAX_STREAM_VOLUME_LEVEL = 1.0f; 604 static constexpr float MIN_STREAM_VOLUME_LEVEL = 0.0f; 605 606 // Resets PA audio client and free up resources if any with this API 607 void ResetPAAudioClient(); 608 // For setting some environment variables required while running from hap 609 void SetEnv(); 610 int32_t CorkStream(); 611 612 // Callbacks to be implemented 613 static void PAStreamStateCb(pa_stream *stream, void *userdata); 614 static void PAStreamUnderFlowCb(pa_stream *stream, void *userdata); 615 static void PAContextStateCb(pa_context *context, void *userdata); 616 static void PAStreamReadCb(pa_stream *stream, size_t length, void *userdata); 617 static void PAStreamStartSuccessCb(pa_stream *stream, int32_t success, void *userdata); 618 static void PAStreamStopSuccessCb(pa_stream *stream, int32_t success, void *userdata); 619 static void PAStreamPauseSuccessCb(pa_stream *stream, int32_t success, void *userdata); 620 static void PAStreamWriteCb(pa_stream *stream, size_t length, void *userdata); 621 static void PAStreamDrainSuccessCb(pa_stream *stream, int32_t success, void *userdata); 622 static void PAStreamFlushSuccessCb(pa_stream *stream, int32_t success, void *userdata); 623 static void PAStreamLatencyUpdateCb(pa_stream *stream, void *userdata); 624 static void PAStreamSetBufAttrSuccessCb(pa_stream *stream, int32_t success, void *userdata); 625 626 static void GetSinkInputInfoCb(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata); 627 static void SetPaVolume(const AudioServiceClient &client); 628 }; 629 } // namespace AudioStandard 630 } // namespace OHOS 631 #endif // AUDIO_SERVICE_CLIENT_H 632