Coverage Report

Created: 2025-09-04 06:37

/src/adhd/cras/src/server/cras_ramp.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright 2016 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_ramp.h"
7
8
#include <errno.h>
9
#include <stdlib.h>
10
11
/*
12
 * Struct to hold ramping information.
13
 */
14
struct cras_ramp {
15
  int active;
16
  // Number of frames that have passed after starting ramping.
17
  int ramped_frames;
18
  // The targeted number of frames for whole ramping duration.
19
  int duration_frames;
20
  // The scaler increment that should be added to scaler for
21
  // every frame.
22
  float increment;
23
  // The initial scaler.
24
  float start_scaler;
25
  float target;
26
  // Callback function to call after ramping is done.
27
  void (*cb)(void* data);
28
  // Data passed to cb.
29
  void* cb_data;
30
};
31
32
0
void cras_ramp_destroy(struct cras_ramp* ramp) {
33
0
  free(ramp);
34
0
}
35
36
0
struct cras_ramp* cras_ramp_create() {
37
0
  struct cras_ramp* ramp;
38
0
  ramp = (struct cras_ramp*)malloc(sizeof(*ramp));
39
0
  if (ramp == NULL) {
40
0
    return NULL;
41
0
  }
42
0
  cras_ramp_reset(ramp);
43
0
  return ramp;
44
0
}
45
46
0
int cras_ramp_reset(struct cras_ramp* ramp) {
47
0
  ramp->active = 0;
48
0
  ramp->ramped_frames = 0;
49
0
  ramp->duration_frames = 0;
50
0
  ramp->increment = 0;
51
0
  ramp->start_scaler = 1.0;
52
0
  ramp->target = 1.0;
53
0
  return 0;
54
0
}
55
56
int cras_ramp_start(struct cras_ramp* ramp,
57
                    int mute_ramp,
58
                    float from,
59
                    float to,
60
                    int duration_frames,
61
                    cras_ramp_cb cb,
62
0
                    void* cb_data) {
63
0
  struct cras_ramp_action action;
64
65
0
  if (!ramp) {
66
0
    return -EINVAL;
67
0
  }
68
69
  // if from == to == 0 means we want to mute for duration_frames
70
0
  if (from == to && from != 0) {
71
0
    return 0;
72
0
  }
73
74
  // Get current scaler position so it can serve as new start scaler.
75
0
  action = cras_ramp_get_current_action(ramp);
76
0
  if (action.type == CRAS_RAMP_ACTION_INVALID) {
77
0
    return -EINVAL;
78
0
  }
79
80
  /* Set initial scaler to current scaler so ramping up/down can be
81
   * smoothly switched. */
82
0
  ramp->active = 1;
83
0
  if (action.type == CRAS_RAMP_ACTION_NONE) {
84
0
    ramp->start_scaler = from;
85
0
  } else {
86
    /* If this a mute ramp, we want to match the previous multiplier
87
     * so that there is not a jump in the audio. Otherwise, we are
88
     * applying a volume ramp so we need to multiply |from| by the
89
     * previous scaler so that we can stack volume ramps. */
90
0
    ramp->start_scaler = action.scaler;
91
0
    if (!mute_ramp) {
92
0
      ramp->start_scaler *= from;
93
0
    }
94
0
  }
95
0
  ramp->increment = (to - ramp->start_scaler) / duration_frames;
96
0
  ramp->target = to;
97
0
  ramp->ramped_frames = 0;
98
0
  ramp->duration_frames = duration_frames;
99
0
  ramp->cb = cb;
100
0
  ramp->cb_data = cb_data;
101
0
  return 0;
102
0
}
103
104
struct cras_ramp_action cras_ramp_get_current_action(
105
0
    const struct cras_ramp* ramp) {
106
0
  struct cras_ramp_action action;
107
108
0
  if (ramp->ramped_frames < 0) {
109
0
    action.type = CRAS_RAMP_ACTION_INVALID;
110
0
    action.scaler = 1.0;
111
0
    action.increment = 0.0;
112
0
    action.target = 1.0;
113
0
  } else if (ramp->active) {
114
0
    action.type = CRAS_RAMP_ACTION_PARTIAL;
115
0
    action.scaler = ramp->start_scaler + ramp->ramped_frames * ramp->increment;
116
0
    action.increment = ramp->increment;
117
0
    action.target = ramp->target;
118
0
  } else {
119
0
    action.type = CRAS_RAMP_ACTION_NONE;
120
0
    action.scaler = 1.0;
121
0
    action.increment = 0.0;
122
0
    action.target = 1.0;
123
0
  }
124
0
  return action;
125
0
}
126
127
0
int cras_ramp_update_ramped_frames(struct cras_ramp* ramp, int num_frames) {
128
0
  if (!ramp->active) {
129
0
    return -EINVAL;
130
0
  }
131
0
  ramp->ramped_frames += num_frames;
132
0
  if (ramp->ramped_frames >= ramp->duration_frames) {
133
0
    ramp->active = 0;
134
0
    if (ramp->cb && ramp->cb_data) {
135
0
      ramp->cb(ramp->cb_data);
136
0
    }
137
0
  }
138
0
  return 0;
139
0
}