• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 #ifndef LOG_TAG
16 #define LOG_TAG "AudioBlend"
17 #endif
18 
19 #include <cinttypes>
20 #include "audio_common_log.h"
21 #include "audio_channel_blend.h"
22 
23 namespace OHOS {
24 namespace AudioStandard {
AudioBlend()25 AudioBlend::AudioBlend()
26 {
27     blendMode_ = MODE_DEFAULT;
28     format_ = 0;
29     channels_ = 0;
30 }
31 
AudioBlend(ChannelBlendMode blendMode,uint8_t format,uint8_t channel)32 AudioBlend::AudioBlend(ChannelBlendMode blendMode, uint8_t format, uint8_t channel)
33     :blendMode_(blendMode), format_(format), channels_(channel)
34 {
35 }
36 
SetParams(ChannelBlendMode blendMode,uint8_t format,uint8_t channel)37 void AudioBlend::SetParams(ChannelBlendMode blendMode, uint8_t format, uint8_t channel)
38 {
39     AUDIO_DEBUG_LOG("SetParams blendMode_:%{public}d format_:%{public}d channels_:%{public}d",
40         blendMode_, format_, channels_);
41     blendMode_ = blendMode;
42     format_ = format;
43     channels_ = channel;
44 }
45 
Process(uint8_t * buffer,size_t bufferSize)46 void AudioBlend::Process(uint8_t *buffer, size_t bufferSize)
47 {
48     switch (format_) {
49         case AudioSampleFormat::SAMPLE_U8:
50             ProcessWithBlendMode<uint8_t>(reinterpret_cast<uint8_t*>(buffer), bufferSize);
51             break;
52         case AudioSampleFormat::SAMPLE_S16LE:
53             ProcessWithBlendMode<int16_t>(reinterpret_cast<int16_t*>(buffer), bufferSize);
54             break;
55         case AudioSampleFormat::SAMPLE_S24LE:
56             ProcessWithBlendMode<int24_t>(reinterpret_cast<int24_t*>(buffer), bufferSize);
57             break;
58         case AudioSampleFormat::SAMPLE_S32LE:
59             ProcessWithBlendMode<int32_t>(reinterpret_cast<int32_t*>(buffer), bufferSize);
60             break;
61         case AudioSampleFormat::SAMPLE_F32LE:
62             ProcessWithBlendMode<float>(reinterpret_cast<float*>(buffer), bufferSize);
63             break;
64         default:
65             break;
66     }
67 }
68 
69 template<typename T>
ProcessWithBlendMode(T * buffer,size_t bufferSize)70 void AudioBlend::ProcessWithBlendMode(T *buffer, size_t bufferSize)
71 {
72     if (channels_ == 0) {
73         return;
74     }
75 
76     uint32_t frameCount = 0;
77     size_t bitWidthSize = GetAudioFormatSize();
78     frameCount = bufferSize / (channels_ * bitWidthSize);
79     switch (blendMode_) {
80         case MODE_BLEND_LR:
81             ProcessBlendLRModeWithFormat<T>(buffer, frameCount, (AudioChannel)channels_);
82             break;
83         case MODE_ALL_LEFT:
84             ProcessAllLeftModeWithFormat<T>(buffer, frameCount, (AudioChannel)channels_);
85             break;
86         case MODE_ALL_RIGHT:
87             ProcessAllRightModeWithFormat<T>(buffer, frameCount, (AudioChannel)channels_);
88             break;
89         default:
90             break;
91     }
92 }
93 
94 template <typename T>
BlendLR(T & left,T & right)95 void AudioBlend::BlendLR(T& left, T& right)
96 {
97     left = left / 2 + right / 2;
98     right = left;
99 }
100 
101 template <>
BlendLR(int24_t & left,int24_t & right)102 void AudioBlend::BlendLR(int24_t& left, int24_t& right)
103 {
104     left.value[0] = left.value[0] / 2 + right.value[0] / 2;
105     right.value[0] = left.value[0];
106     left.value[1] = left.value[1] / 2 + right.value[1] / 2;
107     right.value[0] = left.value[0];
108     left.value[2] = left.value[2] / 2 + right.value[2] / 2;
109     right.value[2] = left.value[2];
110 }
111 
112 template <typename T>
ProcessBlendLRModeWithFormat(T * buffer,size_t count,AudioChannel channel)113 void AudioBlend::ProcessBlendLRModeWithFormat(T *buffer, size_t count, AudioChannel channel)
114 {
115     for (uint32_t i = count; i > 0; i--) {
116         switch (channel) {
117             case CHANNEL_8:
118                 BlendLR(buffer[CHANNEL_SEVEN], buffer[CHANNEL_EIGHT]);
119                 [[fallthrough]];
120             case CHANNEL_7:
121             case CHANNEL_6:
122                 BlendLR(buffer[CHANNEL_FIVE], buffer[CHANNEL_SIX]);
123                 BlendLR(buffer[CHANNEL_ONE], buffer[CHANNEL_TWO]);
124                 break;
125             case CHANNEL_5:
126             case CHANNEL_4:
127                 BlendLR(buffer[CHANNEL_THREE], buffer[CHANNEL_FOUR]);
128                 [[fallthrough]];
129             case CHANNEL_3:
130             case STEREO:
131                 BlendLR(buffer[CHANNEL_ONE], buffer[CHANNEL_TWO]);
132                 break;
133             default:
134                 break;
135         }
136         buffer += (int8_t)channel;
137     }
138 }
139 
140 template <typename T>
ProcessAllLeftModeWithFormat(T * buffer,size_t count,AudioChannel channel)141 void AudioBlend::ProcessAllLeftModeWithFormat(T *buffer, size_t count, AudioChannel channel)
142 {
143     for (uint32_t i = count; i > 0; i--) {
144         switch (channel) {
145             case CHANNEL_8:
146                 buffer[CHANNEL_EIGHT] = buffer[CHANNEL_SEVEN];
147                 [[fallthrough]];
148             case CHANNEL_7:
149             case CHANNEL_6:
150                 buffer[CHANNEL_SIX] = buffer[CHANNEL_FIVE];
151                 buffer[CHANNEL_TWO] = buffer[CHANNEL_ONE];
152                 break;
153             case CHANNEL_5:
154             case CHANNEL_4:
155                 buffer[CHANNEL_FOUR] = buffer[CHANNEL_THREE];
156                 [[fallthrough]];
157             case CHANNEL_3:
158             case STEREO:
159                 buffer[CHANNEL_TWO] = buffer[CHANNEL_ONE];
160                 break;
161             default:
162                 break;
163         }
164         buffer += (int8_t)channel;
165     }
166 }
167 
168 template <typename T>
ProcessAllRightModeWithFormat(T * buffer,size_t count,AudioChannel channel)169 void AudioBlend::ProcessAllRightModeWithFormat(T *buffer, size_t count, AudioChannel channel)
170 {
171     for (uint32_t i = count; i > 0; i--) {
172         switch (channel) {
173             case CHANNEL_8:
174                 buffer[CHANNEL_SEVEN] = buffer[CHANNEL_EIGHT];
175                 [[fallthrough]];
176             case CHANNEL_7:
177             case CHANNEL_6:
178                 buffer[CHANNEL_FIVE] = buffer[CHANNEL_SIX];
179                 buffer[CHANNEL_ONE] = buffer[CHANNEL_TWO];
180                 break;
181             case CHANNEL_5:
182             case CHANNEL_4:
183                 buffer[CHANNEL_THREE] = buffer[CHANNEL_FOUR];
184                 [[fallthrough]];
185             case CHANNEL_3:
186             case STEREO:
187                 buffer[CHANNEL_ONE] = buffer[CHANNEL_TWO];
188                 break;
189             default:
190                 break;
191         }
192         buffer += (int8_t)channel;
193     }
194 }
195 
GetAudioFormatSize()196 size_t AudioBlend::GetAudioFormatSize()
197 {
198     size_t bitWidthSize = 2; // size is 2
199     switch (format_) {
200         case AudioSampleFormat::SAMPLE_U8:
201             bitWidthSize = 1; // size is 1
202             break;
203         case AudioSampleFormat::SAMPLE_S16LE:
204             bitWidthSize = 2; // size is 2
205             break;
206         case AudioSampleFormat::SAMPLE_S24LE:
207             bitWidthSize = 3; // size is 3
208             break;
209         case AudioSampleFormat::SAMPLE_S32LE:
210         case AudioSampleFormat::SAMPLE_F32LE:
211             bitWidthSize = 4; // size is 4
212             break;
213         default:
214             bitWidthSize = 2; // size is 2
215             break;
216     }
217     return bitWidthSize;
218 }
219 
220 template void AudioBlend::ProcessBlendLRModeWithFormat(uint8_t *buffer, size_t count, AudioChannel channel);
221 template void AudioBlend::ProcessBlendLRModeWithFormat(int16_t *buffer, size_t count, AudioChannel channel);
222 template void AudioBlend::ProcessBlendLRModeWithFormat(int24_t *buffer, size_t count, AudioChannel channel);
223 template void AudioBlend::ProcessBlendLRModeWithFormat(int32_t *buffer, size_t count, AudioChannel channel);
224 template void AudioBlend::ProcessBlendLRModeWithFormat(float *buffer, size_t count, AudioChannel channel);
225 
226 template void AudioBlend::ProcessAllLeftModeWithFormat(uint8_t *buffer, size_t count, AudioChannel channel);
227 template void AudioBlend::ProcessAllLeftModeWithFormat(int16_t *buffer, size_t count, AudioChannel channel);
228 template void AudioBlend::ProcessAllLeftModeWithFormat(int24_t *buffer, size_t count, AudioChannel channel);
229 template void AudioBlend::ProcessAllLeftModeWithFormat(int32_t *buffer, size_t count, AudioChannel channel);
230 template void AudioBlend::ProcessAllLeftModeWithFormat(float *buffer, size_t count, AudioChannel channel);
231 
232 template void AudioBlend::ProcessAllRightModeWithFormat(uint8_t *buffer, size_t count, AudioChannel channel);
233 template void AudioBlend::ProcessAllRightModeWithFormat(int16_t *buffer, size_t count, AudioChannel channel);
234 template void AudioBlend::ProcessAllRightModeWithFormat(int24_t *buffer, size_t count, AudioChannel channel);
235 template void AudioBlend::ProcessAllRightModeWithFormat(int32_t *buffer, size_t count, AudioChannel channel);
236 template void AudioBlend::ProcessAllRightModeWithFormat(float *buffer, size_t count, AudioChannel channel);
237 } // namespace AudioStandard
238 } // namespace OHOS
239