1 /*
2  * Copyright (c) 2020-2021 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 #include "recorder_audio_source.h"
17 #include "media_log.h"
18 
19 namespace OHOS {
20 namespace Media {
21 #define CHK_NULL_RETURN(ptr) \
22 do { \
23     if (ptr == nullptr) { \
24         MEDIA_ERR_LOG("ptr null"); \
25         return -1; \
26     } \
27 } while (0)
28 
29 const int64_t AUDIO_SOURCE_TIME_US_S = 1000000ULL;   /* us to s */
30 const int64_t AUDIO_SOURCE_TIME_NS_US = 1000ULL;     /* ns  to us */
31 
RecorderAudioSource()32 RecorderAudioSource::RecorderAudioSource()
33     :audioCap_(new(std::nothrow) AudioCapturerImpl()),
34      framesize_(0),
35      buffer_(nullptr),
36      frameSeq_(0)
37 {
38 }
39 
~RecorderAudioSource()40 RecorderAudioSource::~RecorderAudioSource()
41 {
42     if (buffer_) {
43         delete buffer_;
44         buffer_ = nullptr;
45     }
46 }
47 
Init(const RecorderAudioSourceConfig & sourceConfig)48 int32_t RecorderAudioSource::Init(const RecorderAudioSourceConfig &sourceConfig)
49 {
50     CHK_NULL_RETURN(audioCap_);
51     int32_t ret = 0;
52     AudioCapturerInfo info;
53     info.inputSource = sourceConfig.inputSource;
54     info.audioFormat = sourceConfig.audioFormat;
55     info.sampleRate = sourceConfig.sampleRate;
56     info.channelCount = sourceConfig.channelCount;
57     info.bitRate = sourceConfig.bitRate;
58     info.streamType = TYPE_MEDIA;
59     info.bitWidth = BIT_WIDTH_16;
60     if ((ret = audioCap_->SetCapturerInfo(info)) != SUCCESS) {
61         MEDIA_ERR_LOG("Can't AudioCapturerImpl ret:x%x", ret);
62         return ret;
63     }
64     uint64_t frameCnt = audioCap_->GetFrameCount();
65     framesize_ = static_cast<uint32_t>((frameCnt * info.channelCount * info.bitWidth) / sizeof(uint8_t));
66     if (framesize_ == 0) {
67         MEDIA_ERR_LOG("Can't get framesize");
68         return ERR_UNKNOWN;
69     }
70     buffer_ = new (std::nothrow) uint8_t[framesize_];
71     if (buffer_ == nullptr) {
72         MEDIA_ERR_LOG("new buffer_ nullptr");
73         return ERR_UNKNOWN;
74     }
75     MEDIA_DEBUG_LOG("framesize_ %u", framesize_);
76     return SUCCESS;
77 }
78 
Start()79 int32_t RecorderAudioSource::Start()
80 {
81     if (audioCap_ == nullptr || !audioCap_->Record()) {
82         MEDIA_ERR_LOG("AudioCapturerImpl Can't Start");
83         return ERR_UNKNOWN;
84     }
85     return SUCCESS;
86 }
87 
Int64Multiple(int64_t firstNumber,int64_t secondNumber,int64_t & result)88 static int32_t Int64Multiple(int64_t firstNumber, int64_t secondNumber, int64_t &result)
89 {
90     if (secondNumber == 0) {
91         result = 0;
92         return SUCCESS;
93     }
94 
95     const int64_t int64Max = 0x7fffffffffffffff;
96     if (firstNumber > (int64Max / secondNumber)) {
97         return ERR_INVALID_OPERATION;
98     }
99     result = firstNumber * secondNumber;
100     return SUCCESS;
101 }
102 
AcquireBuffer(RecorderSourceBuffer & buffer,bool isBlocking)103 int32_t RecorderAudioSource::AcquireBuffer(RecorderSourceBuffer &buffer, bool isBlocking)
104 {
105     CHK_NULL_RETURN(audioCap_);
106     int32_t readLen = audioCap_->Read(buffer_, framesize_, isBlocking);
107     if (readLen <= SUCCESS || readLen > static_cast<int32_t>(framesize_)) {
108         MEDIA_ERR_LOG("AudioCapturerImpl Read failed ret:0x%x", readLen);
109         return ERR_READ_BUFFER;
110     }
111     frameSeq_++;
112     buffer.keyFrameFlag = false;
113     buffer.dataAddr = buffer_;
114     buffer.dataLen = readLen;
115     buffer.dataSeq = frameSeq_;
116     Timestamp timestamp;
117     Timestamp::Timebase base = Timestamp::Timebase::MONOTONIC;
118     if (!audioCap_->GetTimestamp(timestamp, base)) {
119         MEDIA_ERR_LOG("AudioCapturerImpl Can't GetTimestamp");
120         return ERR_READ_BUFFER;
121     }
122     int64_t timeStampSecPart = 0;
123     if (Int64Multiple(static_cast<int64_t>(timestamp.time.tv_sec),
124         AUDIO_SOURCE_TIME_US_S, timeStampSecPart) != 0) {
125         MEDIA_ERR_LOG("multiple overflow, use default zero");
126     }
127     buffer.timeStamp = timeStampSecPart + timestamp.time.tv_nsec / AUDIO_SOURCE_TIME_NS_US;
128     return SUCCESS;
129 }
130 
ReleaseBuffer(RecorderSourceBuffer & buffer)131 int32_t RecorderAudioSource::ReleaseBuffer(RecorderSourceBuffer &buffer)
132 {
133     return SUCCESS;
134 }
135 
Stop()136 int32_t RecorderAudioSource::Stop()
137 {
138     if (audioCap_ == nullptr || !audioCap_->Stop()) {
139         MEDIA_ERR_LOG("AudioCapturerImpl Can't Stop");
140         return ERR_UNKNOWN;
141     }
142     return SUCCESS;
143 }
144 
Resume()145 int32_t RecorderAudioSource::Resume()
146 {
147     return SUCCESS;
148 }
149 
Pause()150 int32_t RecorderAudioSource::Pause()
151 {
152     return SUCCESS;
153 }
154 
Release()155 int32_t RecorderAudioSource::Release()
156 {
157     if (audioCap_ == nullptr || !audioCap_->Release()) {
158         MEDIA_ERR_LOG("AudioCapturerImpl Can't Release");
159         return ERR_UNKNOWN;
160     }
161     return SUCCESS;
162 }
163 }  // namespace Media
164 }  // namespace OHOS
165