2 * Copyright (C) 2014 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <cutils/list.h>
18 #include <cutils/log.h>
19 #include <system/thread_defs.h>
21 #include <hardware/audio_effect.h>
22 #include <tinyalsa/asoundlib.h>
23 #include <audio_effects/effect_visualizer.h>
27 EFFECT_STATE_UNINITIALIZED
,
28 EFFECT_STATE_INITIALIZED
,
32 typedef struct effect_context_s effect_context_t
;
33 typedef struct output_context_s output_context_t
;
36 /* effect specific operations. Only the init() and process() operations must be defined.
37 * Others are optional.
39 typedef struct effect_ops_s
{
40 int (*init
)(effect_context_t
*context
);
41 int (*release
)(effect_context_t
*context
);
42 int (*reset
)(effect_context_t
*context
);
43 int (*enable
)(effect_context_t
*context
);
44 int (*disable
)(effect_context_t
*context
);
45 int (*start
)(effect_context_t
*context
, output_context_t
*output
);
46 int (*stop
)(effect_context_t
*context
, output_context_t
*output
);
47 int (*process
)(effect_context_t
*context
, audio_buffer_t
*in
, audio_buffer_t
*out
);
48 int (*set_parameter
)(effect_context_t
*context
, effect_param_t
*param
, uint32_t size
);
49 int (*get_parameter
)(effect_context_t
*context
, effect_param_t
*param
, uint32_t *size
);
50 int (*command
)(effect_context_t
*context
, uint32_t cmd_code
, uint32_t cmd_size
, void *cmd_data
, uint32_t *reply_size
, void *reply_data
);
53 struct effect_context_s
{
54 const struct effect_interface_s
*itfe
;
56 struct listnode effects_list_node
; /* node in created_effects_list */
57 struct listnode output_node
; /* node in output_context_t.effects_list */
58 effect_config_t config
;
59 const effect_descriptor_t
*desc
;
60 audio_io_handle_t out_handle
; /* io handle of the output the effect is attached to */
62 bool offload_enabled
; /* when offload is enabled we process VISUALIZER_CMD_CAPTURE command.
63 Otherwise non offloaded visualizer has already processed the command
64 and we must not overwrite the reply. */
68 typedef struct output_context_s
{
69 struct listnode outputs_list_node
; /* node in active_outputs_list */
70 audio_io_handle_t handle
; /* io handle */
71 struct listnode effects_list
; /* list of effects attached to this output */
76 /* maximum time since last capture buffer update before resetting capture buffer. This means
77 that the framework has stopped playing audio and we must start returning silence */
78 #define MAX_STALL_TIME_MS 1000
80 #define CAPTURE_BUF_SIZE 65536 /* "64k should be enough for everyone" */
82 #define DISCARD_MEASUREMENTS_TIME_MS 2000 /* discard measurements older than this number of ms */
84 /* maximum number of buffers for which we keep track of the measurements */
85 #define MEASUREMENT_WINDOW_MAX_SIZE_IN_BUFFERS 25 /* note: buffer index is stored in uint8_t */
87 typedef struct buffer_stats_s
{
89 uint16_t peak_u16
; /* the positive peak of the absolute value of the samples in a buffer */
90 float rms_squared
; /* the average square of the samples in a buffer */
93 typedef struct visualizer_context_s
{
94 effect_context_t common
;
97 uint32_t capture_size
;
98 uint32_t scaling_mode
;
99 uint32_t last_capture_idx
;
101 struct timespec buffer_update_time
;
102 uint8_t capture_buf
[CAPTURE_BUF_SIZE
];
103 /* for measurements */
104 uint8_t channel_count
; /* to avoid recomputing it every time a buffer is processed */
106 uint8_t meas_wndw_size_in_buffers
;
107 uint8_t meas_buffer_idx
;
108 buffer_stats_t past_meas
[MEASUREMENT_WINDOW_MAX_SIZE_IN_BUFFERS
];
109 } visualizer_context_t
;
112 #define DSP_OUTPUT_LATENCY_MS 0 /* Fudge factor for latency after capture point in audio DSP */
115 #define CAPTURE_DEVICE 8
117 /* Proxy port supports only MMAP read and those fixed parameters*/
118 #define AUDIO_CAPTURE_CHANNEL_COUNT 2
119 #define AUDIO_CAPTURE_SMP_RATE 48000
120 #define AUDIO_CAPTURE_PERIOD_SIZE 1024
121 #define AUDIO_CAPTURE_PERIOD_COUNT 4
123 struct pcm_config pcm_config_capture
= {
124 .channels
= AUDIO_CAPTURE_CHANNEL_COUNT
,
125 .rate
= AUDIO_CAPTURE_SMP_RATE
,
126 .period_size
= AUDIO_CAPTURE_PERIOD_SIZE
,
127 .period_count
= AUDIO_CAPTURE_PERIOD_COUNT
,
128 .format
= PCM_FORMAT_S16_LE
,
129 .start_threshold
= AUDIO_CAPTURE_PERIOD_SIZE
/ 4,
130 .stop_threshold
= INT_MAX
,
131 .avail_min
= AUDIO_CAPTURE_PERIOD_SIZE
/ 4,