/src/adhd/cras/src/server/cras_audio_area.c
Line | Count | Source |
1 | | /* Copyright 2014 The ChromiumOS Authors |
2 | | * Use of this source code is governed by a BSD-style license that can be |
3 | | * found in the LICENSE file. |
4 | | */ |
5 | | |
6 | | #include "cras/src/server/cras_audio_area.h" |
7 | | |
8 | | #include <stdint.h> |
9 | | #include <stdlib.h> |
10 | | #include <string.h> |
11 | | #include <sys/param.h> |
12 | | |
13 | | #include "cras/src/server/cras_mix.h" |
14 | | #include "cras_audio_format.h" |
15 | | |
16 | 844 | struct cras_audio_area* cras_audio_area_create(size_t num_channels) { |
17 | 844 | struct cras_audio_area* area; |
18 | 844 | size_t sz; |
19 | | |
20 | 844 | sz = sizeof(*area) + num_channels * sizeof(struct cras_channel_area); |
21 | 844 | area = calloc(1, sz); |
22 | 844 | area->num_channels = num_channels; |
23 | | |
24 | 844 | return area; |
25 | 844 | } |
26 | | |
27 | | unsigned int cras_audio_area_copy(const struct cras_audio_area* dst, |
28 | | unsigned int dst_offset, |
29 | | const struct cras_audio_format* dst_fmt, |
30 | | const struct cras_audio_area* src, |
31 | | unsigned int src_offset, |
32 | 52 | float software_gain_scaler) { |
33 | 52 | unsigned int src_idx, dst_idx; |
34 | 52 | unsigned int ncopy; |
35 | 52 | uint8_t *schan, *dchan; |
36 | | |
37 | 52 | ncopy = MIN(src->frames - src_offset, dst->frames - dst_offset); |
38 | | |
39 | | // TODO(dgreid) - this replaces a memcpy, it needs to be way faster. |
40 | 156 | for (src_idx = 0; src_idx < src->num_channels; src_idx++) { |
41 | 524 | for (dst_idx = 0; dst_idx < dst->num_channels; dst_idx++) { |
42 | 420 | if (!(src->channels[src_idx].ch_set & dst->channels[dst_idx].ch_set)) { |
43 | 324 | continue; |
44 | 324 | } |
45 | | |
46 | 96 | schan = src->channels[src_idx].buf + |
47 | 96 | src_offset * src->channels[src_idx].step_bytes; |
48 | 96 | dchan = dst->channels[dst_idx].buf + |
49 | 96 | dst_offset * dst->channels[dst_idx].step_bytes; |
50 | | |
51 | 96 | cras_mix_add_scale_stride(dst_fmt->format, dchan, schan, ncopy, |
52 | 96 | dst->channels[dst_idx].step_bytes, |
53 | 96 | src->channels[src_idx].step_bytes, |
54 | 96 | software_gain_scaler); |
55 | 96 | } |
56 | 104 | } |
57 | | |
58 | 52 | return ncopy; |
59 | 52 | } |
60 | | |
61 | 843 | void cras_audio_area_destroy(struct cras_audio_area* area) { |
62 | 843 | free(area); |
63 | 843 | } |
64 | | |
65 | | void cras_audio_area_config_channels(struct cras_audio_area* area, |
66 | 841 | const struct cras_audio_format* fmt) { |
67 | 841 | unsigned int i, ch; |
68 | | |
69 | | /* For mono, config the channel type to match both front left and front |
70 | | * right. Notice that the stereo-mono conversion is to add up two channels so |
71 | | * the magnitude of mono is louder than stereo. We can't fix it by dividing |
72 | | * by 2 directly because it may cause the recording magnitude decreased for |
73 | | * some camera mic users. |
74 | | * TODO(hychao): add more mapping when we have like {FL, FC} |
75 | | * for mono + kb mic. |
76 | | */ |
77 | 841 | if ((fmt->num_channels == 1) && ((fmt->channel_layout[CRAS_CH_FC] == 0) || |
78 | 119 | (fmt->channel_layout[CRAS_CH_FL] == 0))) { |
79 | 119 | channel_area_set_channel(area->channels, CRAS_CH_FL); |
80 | 119 | channel_area_set_channel(area->channels, CRAS_CH_FR); |
81 | 119 | return; |
82 | 119 | } |
83 | | |
84 | 3.93k | for (i = 0; i < fmt->num_channels; i++) { |
85 | 3.21k | area->channels[i].ch_set = 0; |
86 | 38.5k | for (ch = 0; ch < CRAS_CH_MAX; ch++) { |
87 | 35.3k | if (fmt->channel_layout[ch] == i) { |
88 | 5.13k | channel_area_set_channel(&area->channels[i], ch); |
89 | 5.13k | } |
90 | 35.3k | } |
91 | 3.21k | } |
92 | 722 | } |
93 | | |
94 | | void cras_audio_area_config_buf_pointers(struct cras_audio_area* area, |
95 | | const struct cras_audio_format* fmt, |
96 | 595 | uint8_t* base_buffer) { |
97 | 595 | int i; |
98 | 595 | const int sample_size = snd_pcm_format_physical_width(fmt->format) / 8; |
99 | | |
100 | | // TODO(dgreid) - assuming interleaved audio here for now. |
101 | 1.89k | for (i = 0; i < area->num_channels; i++) { |
102 | 1.29k | area->channels[i].step_bytes = cras_get_format_bytes(fmt); |
103 | 1.29k | area->channels[i].buf = base_buffer + i * sample_size; |
104 | 1.29k | } |
105 | 595 | } |