• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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