Coverage Report

Created: 2026-03-28 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}