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 frameCount = bufferSize / (channels_ * (format_ + 1));
78 switch (blendMode_) {
79 case MODE_BLEND_LR:
80 ProcessBlendLRModeWithFormat<T>(buffer, frameCount, (AudioChannel)channels_);
81 break;
82 case MODE_ALL_LEFT:
83 ProcessAllLeftModeWithFormat<T>(buffer, frameCount, (AudioChannel)channels_);
84 break;
85 case MODE_ALL_RIGHT:
86 ProcessAllRightModeWithFormat<T>(buffer, frameCount, (AudioChannel)channels_);
87 break;
88 default:
89 break;
90 }
91 }
92
93 template <typename T>
BlendLR(T & left,T & right)94 void AudioBlend::BlendLR(T& left, T& right)
95 {
96 left = left / 2 + right / 2;
97 right = left;
98 }
99
100 template <>
BlendLR(int24_t & left,int24_t & right)101 void AudioBlend::BlendLR(int24_t& left, int24_t& right)
102 {
103 left.value[0] = left.value[0] / 2 + right.value[0] / 2;
104 right.value[0] = left.value[0];
105 left.value[1] = left.value[1] / 2 + right.value[1] / 2;
106 right.value[0] = left.value[0];
107 left.value[2] = left.value[2] / 2 + right.value[2] / 2;
108 right.value[2] = left.value[2];
109 }
110
111 template <typename T>
ProcessBlendLRModeWithFormat(T * buffer,size_t count,AudioChannel channel)112 void AudioBlend::ProcessBlendLRModeWithFormat(T *buffer, size_t count, AudioChannel channel)
113 {
114 for (uint32_t i = count; i > 0; i--) {
115 switch (channel) {
116 case CHANNEL_8:
117 BlendLR(buffer[CHANNEL_SEVEN], buffer[CHANNEL_EIGHT]);
118 [[fallthrough]];
119 case CHANNEL_7:
120 case CHANNEL_6:
121 BlendLR(buffer[CHANNEL_FIVE], buffer[CHANNEL_SIX]);
122 BlendLR(buffer[CHANNEL_ONE], buffer[CHANNEL_TWO]);
123 break;
124 case CHANNEL_5:
125 case CHANNEL_4:
126 BlendLR(buffer[CHANNEL_THREE], buffer[CHANNEL_FOUR]);
127 [[fallthrough]];
128 case CHANNEL_3:
129 case STEREO:
130 BlendLR(buffer[CHANNEL_ONE], buffer[CHANNEL_TWO]);
131 break;
132 default:
133 break;
134 }
135 buffer += (int8_t)channel;
136 }
137 }
138
139 template <typename T>
ProcessAllLeftModeWithFormat(T * buffer,size_t count,AudioChannel channel)140 void AudioBlend::ProcessAllLeftModeWithFormat(T *buffer, size_t count, AudioChannel channel)
141 {
142 for (uint32_t i = count; i > 0; i--) {
143 switch (channel) {
144 case CHANNEL_8:
145 buffer[CHANNEL_EIGHT] = buffer[CHANNEL_SEVEN];
146 [[fallthrough]];
147 case CHANNEL_7:
148 case CHANNEL_6:
149 buffer[CHANNEL_SIX] = buffer[CHANNEL_FIVE];
150 buffer[CHANNEL_TWO] = buffer[CHANNEL_ONE];
151 break;
152 case CHANNEL_5:
153 case CHANNEL_4:
154 buffer[CHANNEL_FOUR] = buffer[CHANNEL_THREE];
155 [[fallthrough]];
156 case CHANNEL_3:
157 case STEREO:
158 buffer[CHANNEL_TWO] = buffer[CHANNEL_ONE];
159 break;
160 default:
161 break;
162 }
163 buffer += (int8_t)channel;
164 }
165 }
166
167 template <typename T>
ProcessAllRightModeWithFormat(T * buffer,size_t count,AudioChannel channel)168 void AudioBlend::ProcessAllRightModeWithFormat(T *buffer, size_t count, AudioChannel channel)
169 {
170 for (uint32_t i = count; i > 0; i--) {
171 switch (channel) {
172 case CHANNEL_8:
173 buffer[CHANNEL_SEVEN] = buffer[CHANNEL_EIGHT];
174 [[fallthrough]];
175 case CHANNEL_7:
176 case CHANNEL_6:
177 buffer[CHANNEL_FIVE] = buffer[CHANNEL_SIX];
178 buffer[CHANNEL_ONE] = buffer[CHANNEL_TWO];
179 break;
180 case CHANNEL_5:
181 case CHANNEL_4:
182 buffer[CHANNEL_THREE] = buffer[CHANNEL_FOUR];
183 [[fallthrough]];
184 case CHANNEL_3:
185 case STEREO:
186 buffer[CHANNEL_ONE] = buffer[CHANNEL_TWO];
187 break;
188 default:
189 break;
190 }
191 buffer += (int8_t)channel;
192 }
193 }
194
195 template void AudioBlend::ProcessBlendLRModeWithFormat(uint8_t *buffer, size_t count, AudioChannel channel);
196 template void AudioBlend::ProcessBlendLRModeWithFormat(int16_t *buffer, size_t count, AudioChannel channel);
197 template void AudioBlend::ProcessBlendLRModeWithFormat(int24_t *buffer, size_t count, AudioChannel channel);
198 template void AudioBlend::ProcessBlendLRModeWithFormat(int32_t *buffer, size_t count, AudioChannel channel);
199
200 template void AudioBlend::ProcessAllLeftModeWithFormat(uint8_t *buffer, size_t count, AudioChannel channel);
201 template void AudioBlend::ProcessAllLeftModeWithFormat(int16_t *buffer, size_t count, AudioChannel channel);
202 template void AudioBlend::ProcessAllLeftModeWithFormat(int24_t *buffer, size_t count, AudioChannel channel);
203 template void AudioBlend::ProcessAllLeftModeWithFormat(int32_t *buffer, size_t count, AudioChannel channel);
204
205 template void AudioBlend::ProcessAllRightModeWithFormat(uint8_t *buffer, size_t count, AudioChannel channel);
206 template void AudioBlend::ProcessAllRightModeWithFormat(int16_t *buffer, size_t count, AudioChannel channel);
207 template void AudioBlend::ProcessAllRightModeWithFormat(int24_t *buffer, size_t count, AudioChannel channel);
208 template void AudioBlend::ProcessAllRightModeWithFormat(int32_t *buffer, size_t count, AudioChannel channel);
209 } // namespace AudioStandard
210 } // namespace OHOS
211