Skip to content

Commit c445bbd

Browse files
singalsulgirdwood
authored andcommitted
Audio: PCM converter: Add mu-law format conversion
This patch adds to the PCM converter functions pcm_convert_mulaw_to_s32() and pcm_convert_s32_to_mulaw(). The header files with support functions are updated to handle the format. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
1 parent c265ce3 commit c445bbd

5 files changed

Lines changed: 89 additions & 0 deletions

File tree

src/audio/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,11 @@ config FORMAT_A_LAW
185185
help
186186
Support 8 bit A-law processing data format.
187187

188+
config FORMAT_MU_LAW
189+
bool "Support mu-law"
190+
help
191+
Support 8 bit mu-law processing data format.
192+
188193
config FORMAT_S16LE
189194
bool "Support S16LE"
190195
default y
@@ -239,6 +244,12 @@ config PCM_CONVERTER_FORMAT_A_LAW
239244
help
240245
Support 8 bit A-law data format.
241246

247+
config PCM_CONVERTER_FORMAT_MU_LAW
248+
bool "Support mu-law"
249+
select MATH_MU_LAW_CODEC
250+
help
251+
Support 8 bit mu-law data format.
252+
242253
config PCM_CONVERTER_FORMAT_S16LE
243254
bool "Support S16LE"
244255
default y

src/audio/pcm_converter/pcm_converter_generic.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <sof/audio/buffer.h>
2323
#include <sof/audio/format.h>
2424
#include <sof/math/a_law.h>
25+
#include <sof/math/mu_law.h>
2526
#include <rtos/bit.h>
2627
#include <sof/common.h>
2728
#include <sof/compiler_attributes.h>
@@ -154,6 +155,66 @@ static int pcm_convert_s32_to_alaw(const struct audio_stream *source,
154155
}
155156
#endif /* CONFIG_PCM_CONVERTER_FORMAT_A_LAW && CONFIG_PCM_CONVERTER_FORMAT_S32LE */
156157

158+
#if CONFIG_PCM_CONVERTER_FORMAT_MU_LAW && CONFIG_PCM_CONVERTER_FORMAT_S32LE
159+
static int pcm_convert_mulaw_to_s32(const struct audio_stream *source,
160+
uint32_t ioffset, struct audio_stream *sink,
161+
uint32_t ooffset, uint32_t samples, uint32_t chmap)
162+
{
163+
const uint8_t *src = audio_stream_get_rptr(source);
164+
int32_t *dst = audio_stream_get_wptr(sink);
165+
uint32_t processed;
166+
uint32_t nmax, i, n;
167+
168+
src += ioffset;
169+
dst += ooffset;
170+
for (processed = 0; processed < samples; processed += n) {
171+
src = audio_stream_wrap(source, (void *)src);
172+
dst = audio_stream_wrap(sink, dst);
173+
n = samples - processed;
174+
nmax = audio_stream_bytes_without_wrap(source, src) >> BYTES_TO_U8_SAMPLES;
175+
n = MIN(n, nmax);
176+
nmax = audio_stream_bytes_without_wrap(sink, dst) >> BYTES_TO_S32_SAMPLES;
177+
n = MIN(n, nmax);
178+
for (i = 0; i < n; i++) {
179+
*dst = sofm_mu_law_decode(*src) << 16;
180+
src++;
181+
dst++;
182+
}
183+
}
184+
185+
return samples;
186+
}
187+
188+
static int pcm_convert_s32_to_mulaw(const struct audio_stream *source,
189+
uint32_t ioffset, struct audio_stream *sink,
190+
uint32_t ooffset, uint32_t samples, uint32_t chmap)
191+
{
192+
const int32_t *src = audio_stream_get_rptr(source);
193+
uint8_t *dst = audio_stream_get_wptr(sink);
194+
uint32_t processed;
195+
uint32_t nmax, i, n;
196+
197+
src += ioffset;
198+
dst += ooffset;
199+
for (processed = 0; processed < samples; processed += n) {
200+
src = audio_stream_wrap(source, (void *)src);
201+
dst = audio_stream_wrap(sink, dst);
202+
n = samples - processed;
203+
nmax = audio_stream_bytes_without_wrap(source, src) >> BYTES_TO_S32_SAMPLES;
204+
n = MIN(n, nmax);
205+
nmax = audio_stream_bytes_without_wrap(sink, dst) >> BYTES_TO_U8_SAMPLES;
206+
n = MIN(n, nmax);
207+
for (i = 0; i < n; i++) {
208+
*dst = sofm_mu_law_encode(*src >> 16);
209+
src++;
210+
dst++;
211+
}
212+
}
213+
214+
return samples;
215+
}
216+
#endif /* CONFIG_PCM_CONVERTER_FORMAT_MU_LAW && CONFIG_PCM_CONVERTER_FORMAT_S32LE */
217+
157218
#if CONFIG_PCM_CONVERTER_FORMAT_S16LE && CONFIG_PCM_CONVERTER_FORMAT_S24LE
158219

159220
static int pcm_convert_s16_to_s24(const struct audio_stream *source,
@@ -623,6 +684,13 @@ const struct pcm_func_map pcm_func_map[] = {
623684
{ SOF_IPC_FRAME_A_LAW, SOF_IPC_FRAME_S32_LE, pcm_convert_alaw_to_s32 },
624685
{ SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_A_LAW, pcm_convert_s32_to_alaw },
625686
#endif /* CONFIG_PCM_CONVERTER_FORMAT_A_LAW && CONFIG_PCM_CONVERTER_FORMAT_S32LE */
687+
#if CONFIG_PCM_CONVERTER_FORMAT_MU_LAW
688+
{ SOF_IPC_FRAME_MU_LAW, SOF_IPC_FRAME_MU_LAW, just_copy },
689+
#endif /* CONFIG_PCM_CONVERTER_FORMAT_MU_LAW */
690+
#if CONFIG_PCM_CONVERTER_FORMAT_MU_LAW && CONFIG_PCM_CONVERTER_FORMAT_S32LE
691+
{ SOF_IPC_FRAME_MU_LAW, SOF_IPC_FRAME_S32_LE, pcm_convert_mulaw_to_s32 },
692+
{ SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_MU_LAW, pcm_convert_s32_to_mulaw },
693+
#endif /* CONFIG_PCM_CONVERTER_FORMAT_A_LAW && CONFIG_PCM_CONVERTER_FORMAT_S32LE */
626694
#if CONFIG_PCM_CONVERTER_FORMAT_S16LE
627695
{ SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, just_copy },
628696
#endif /* CONFIG_PCM_CONVERTER_FORMAT_S16LE */

src/include/module/audio/format.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ static inline uint32_t get_sample_bytes(enum sof_ipc_frame fmt)
2323
return 3;
2424
case SOF_IPC_FRAME_U8:
2525
case SOF_IPC_FRAME_A_LAW:
26+
case SOF_IPC_FRAME_MU_LAW:
2627
return 1;
2728
default:
2829
return 4;
@@ -39,6 +40,7 @@ static inline uint32_t get_sample_bitdepth(enum sof_ipc_frame fmt)
3940
return 24;
4041
case SOF_IPC_FRAME_U8:
4142
case SOF_IPC_FRAME_A_LAW:
43+
case SOF_IPC_FRAME_MU_LAW:
4244
return 8;
4345
default:
4446
return 32;

src/include/module/ipc/stream.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ enum sof_ipc_frame {
2424
SOF_IPC_FRAME_U8,
2525
SOF_IPC_FRAME_S16_4LE, /* 16-bit in 32-bit container */
2626
SOF_IPC_FRAME_A_LAW,
27+
SOF_IPC_FRAME_MU_LAW,
2728
};
2829

2930
#endif /* __MODULE_IPC_STREAM_H__ */

src/include/sof/audio/audio_stream.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,13 @@ static inline void audio_stream_fmt_conversion(enum ipc4_bit_depth depth,
10351035
}
10361036
#endif
10371037

1038+
#ifdef CONFIG_FORMAT_MU_LAW
1039+
if (type == IPC4_TYPE_MU_LAW && depth == 8) {
1040+
*frame_fmt = SOF_IPC_FRAME_MU_LAW;
1041+
*valid_fmt = SOF_IPC_FRAME_MU_LAW;
1042+
}
1043+
#endif
1044+
10381045
if (valid == 24) {
10391046
#ifdef CONFIG_FORMAT_S24_3LE
10401047
if (depth == 24) {

0 commit comments

Comments
 (0)