diff options
Diffstat (limited to 'lib/rbcodec/dsp/dsp.h')
-rw-r--r-- | lib/rbcodec/dsp/dsp.h | 212 |
1 files changed, 131 insertions, 81 deletions
diff --git a/lib/rbcodec/dsp/dsp.h b/lib/rbcodec/dsp/dsp.h index a99df17468..feac4aa845 100644 --- a/lib/rbcodec/dsp/dsp.h +++ b/lib/rbcodec/dsp/dsp.h | |||
@@ -18,109 +18,159 @@ | |||
18 | * KIND, either express or implied. | 18 | * KIND, either express or implied. |
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | |||
22 | #ifndef _DSP_H | 21 | #ifndef _DSP_H |
23 | #define _DSP_H | 22 | #define _DSP_H |
24 | 23 | ||
25 | #include <stdlib.h> | 24 | struct dsp_config; |
26 | #include <stdbool.h> | ||
27 | 25 | ||
28 | #define NATIVE_FREQUENCY 44100 | 26 | /* Include all this junk here for now */ |
27 | #include "dsp_proc_settings.h" | ||
29 | 28 | ||
30 | enum | 29 | enum dsp_ids |
31 | { | 30 | { |
32 | STEREO_INTERLEAVED = 0, | 31 | CODEC_IDX_AUDIO, |
33 | STEREO_NONINTERLEAVED, | ||
34 | STEREO_MONO, | ||
35 | STEREO_NUM_MODES, | ||
36 | }; | ||
37 | |||
38 | enum | ||
39 | { | ||
40 | CODEC_IDX_AUDIO = 0, | ||
41 | CODEC_IDX_VOICE, | 32 | CODEC_IDX_VOICE, |
33 | DSP_COUNT, | ||
42 | }; | 34 | }; |
43 | 35 | ||
44 | enum | 36 | enum dsp_settings |
45 | { | 37 | { |
46 | DSP_MYDSP = 1, | 38 | DSP_INIT, /* For dsp_init */ |
39 | DSP_RESET, | ||
47 | DSP_SET_FREQUENCY, | 40 | DSP_SET_FREQUENCY, |
48 | DSP_SWITCH_FREQUENCY, | 41 | DSP_SWITCH_FREQUENCY = DSP_SET_FREQUENCY, /* deprecated */ |
49 | DSP_SET_SAMPLE_DEPTH, | 42 | DSP_SET_SAMPLE_DEPTH, |
50 | DSP_SET_STEREO_MODE, | 43 | DSP_SET_STEREO_MODE, |
51 | DSP_RESET, | ||
52 | DSP_FLUSH, | 44 | DSP_FLUSH, |
53 | DSP_SET_TRACK_GAIN, | 45 | DSP_PROC_INIT, |
54 | DSP_SET_ALBUM_GAIN, | 46 | DSP_PROC_CLOSE, |
55 | DSP_SET_TRACK_PEAK, | 47 | DSP_PROC_SETTING, /* stage-specific should be this + id */ |
56 | DSP_SET_ALBUM_PEAK, | ||
57 | DSP_CROSSFEED | ||
58 | }; | 48 | }; |
59 | 49 | ||
50 | #define NATIVE_FREQUENCY 44100 /* internal/output sample rate */ | ||
60 | 51 | ||
61 | /**************************************************************************** | 52 | enum dsp_stereo_modes |
62 | * NOTE: Any assembly routines that use these structures must be updated | ||
63 | * if current data members are moved or changed. | ||
64 | */ | ||
65 | struct resample_data | ||
66 | { | 53 | { |
67 | uint32_t delta; /* 00h */ | 54 | STEREO_INTERLEAVED, |
68 | uint32_t phase; /* 04h */ | 55 | STEREO_NONINTERLEAVED, |
69 | int32_t last_sample[2]; /* 08h */ | 56 | STEREO_MONO, |
70 | /* 10h */ | 57 | STEREO_NUM_MODES, |
71 | }; | 58 | }; |
72 | 59 | ||
73 | /* This is for passing needed data to external dsp routines. If another | 60 | /* Format into for the buffer (if .valid == true) */ |
74 | * dsp parameter needs to be passed, add to the end of the structure | 61 | struct sample_format |
75 | * and remove from dsp_config. | ||
76 | * If another function type becomes assembly/external and requires dsp | ||
77 | * config info, add a pointer paramter of type "struct dsp_data *". | ||
78 | * If removing something from other than the end, reserve the spot or | ||
79 | * else update every implementation for every target. | ||
80 | * Be sure to add the offset of the new member for easy viewing as well. :) | ||
81 | * It is the first member of dsp_config and all members can be accessesed | ||
82 | * through the main aggregate but this is intended to make a safe haven | ||
83 | * for these items whereas the c part can be rearranged at will. dsp_data | ||
84 | * could even moved within dsp_config without disurbing the order. | ||
85 | */ | ||
86 | struct dsp_data | ||
87 | { | 62 | { |
88 | int output_scale; /* 00h */ | 63 | uint8_t changed; /* 00h: 0=no change, 1=changed (is also index) */ |
89 | int num_channels; /* 04h */ | 64 | uint8_t num_channels; /* 01h: number of channels of data */ |
90 | struct resample_data resample_data; /* 08h */ | 65 | uint8_t frac_bits; /* 02h: number of fractional bits */ |
91 | int32_t clip_min; /* 18h */ | 66 | uint8_t output_scale; /* 03h: output scaling shift */ |
92 | int32_t clip_max; /* 1ch */ | 67 | int32_t frequency; /* 04h: pitch-adjusted sample rate */ |
93 | int32_t gain; /* 20h - Note that this is in S8.23 format. */ | 68 | int32_t codec_frequency; /* 08h: codec-specifed sample rate */ |
94 | int frac_bits; /* 24h */ | 69 | /* 0ch */ |
95 | /* 28h */ | ||
96 | }; | 70 | }; |
97 | 71 | ||
98 | struct dsp_config; | 72 | /* Compare format data only */ |
73 | #define EQU_SAMPLE_FORMAT(f1, f2) \ | ||
74 | (!memcmp(&(f1).num_channels, &(f2).num_channels, \ | ||
75 | sizeof (f1) - sizeof ((f1).changed))) | ||
76 | |||
77 | static inline void format_change_set(struct sample_format *f) | ||
78 | { f->changed = 1; } | ||
79 | static inline void format_change_ack(struct sample_format *f) | ||
80 | { f->changed = 0; } | ||
99 | 81 | ||
100 | int dsp_process(struct dsp_config *dsp, char *dest, | 82 | /* Used by ASM routines - keep field order or else fix the functions */ |
101 | const char *src[], int count); | 83 | struct dsp_buffer |
102 | int dsp_input_count(struct dsp_config *dsp, int count); | 84 | { |
103 | int dsp_output_count(struct dsp_config *dsp, int count); | 85 | int32_t remcount; /* 00h: Samples in buffer (In, Int, Out) */ |
104 | intptr_t dsp_configure(struct dsp_config *dsp, int setting, | 86 | union |
87 | { | ||
88 | const void *pin[2]; /* 04h: Channel pointers (In) */ | ||
89 | int32_t *p32[2]; /* 04h: Channel pointers (Int) */ | ||
90 | int16_t *p16out; /* 04h: DSP output buffer (Out) */ | ||
91 | }; | ||
92 | union | ||
93 | { | ||
94 | uint32_t proc_mask; /* 0Ch: In-place effects already appled to buffer | ||
95 | in order to avoid double-processing. Set | ||
96 | to zero on new buffer before passing to | ||
97 | DSP. */ | ||
98 | int bufcount; /* 0Ch: Buffer length/dest buffer remaining | ||
99 | Basically, pay no attention unless it's | ||
100 | *your* new buffer and is used internally | ||
101 | or is specifically the final output | ||
102 | buffer. */ | ||
103 | }; | ||
104 | struct sample_format format; /* 10h: Buffer format data */ | ||
105 | /* 1ch */ | ||
106 | }; | ||
107 | |||
108 | /* Remove samples from input buffer (In). Sample size is specified. | ||
109 | Provided to dsp_process(). */ | ||
110 | static inline void dsp_advance_buffer_input(struct dsp_buffer *buf, | ||
111 | int by_count, | ||
112 | size_t size_each) | ||
113 | { | ||
114 | buf->remcount -= by_count; | ||
115 | buf->pin[0] += by_count * size_each; | ||
116 | buf->pin[1] += by_count * size_each; | ||
117 | } | ||
118 | |||
119 | /* Add samples to output buffer and update remaining space (Out). | ||
120 | Provided to dsp_process() */ | ||
121 | static inline void dsp_advance_buffer_output(struct dsp_buffer *buf, | ||
122 | int by_count) | ||
123 | { | ||
124 | buf->bufcount -= by_count; | ||
125 | buf->remcount += by_count; | ||
126 | buf->p16out += 2 * by_count; /* Interleaved stereo */ | ||
127 | } | ||
128 | |||
129 | /* Remove samples from internal input buffer (In, Int). | ||
130 | Provided to dsp_process() or by another processing stage. */ | ||
131 | static inline void dsp_advance_buffer32(struct dsp_buffer *buf, | ||
132 | int by_count) | ||
133 | { | ||
134 | buf->remcount -= by_count; | ||
135 | buf->p32[0] += by_count; | ||
136 | buf->p32[1] += by_count; | ||
137 | } | ||
138 | |||
139 | /** For use by processing stages **/ | ||
140 | |||
141 | #define DSP_PRINT_FORMAT(name, id, format) \ | ||
142 | DEBUGF("DSP format- " #name "\n" \ | ||
143 | " id:%d chg:%c ch:%u fb:%u os:%u hz:%u chz:%u\n", \ | ||
144 | (int)id, \ | ||
145 | (format).changed ? 'y' : 'n', \ | ||
146 | (unsigned int)(format).num_channels, \ | ||
147 | (unsigned int)(format).frac_bits, \ | ||
148 | (unsigned int)(format).output_scale, \ | ||
149 | (unsigned int)(format).frequency, \ | ||
150 | (unsigned int)(format).codec_frequency); | ||
151 | |||
152 | /* Get DSP pointer */ | ||
153 | struct dsp_config * dsp_get_config(enum dsp_ids id); | ||
154 | |||
155 | /* Get DSP id */ | ||
156 | enum dsp_ids dsp_get_id(const struct dsp_config *dsp); | ||
157 | |||
158 | #if 0 /* Not needed now but enable if something must know this */ | ||
159 | /* Is the DSP processing a buffer? */ | ||
160 | bool dsp_is_busy(const struct dsp_config *dsp); | ||
161 | #endif /* 0 */ | ||
162 | |||
163 | /** General DSP processing **/ | ||
164 | |||
165 | /* Process the given buffer - see implementation in dsp.c for more */ | ||
166 | void dsp_process(struct dsp_config *dsp, struct dsp_buffer *src, | ||
167 | struct dsp_buffer *dst); | ||
168 | |||
169 | /* Change DSP settings */ | ||
170 | intptr_t dsp_configure(struct dsp_config *dsp, unsigned int setting, | ||
105 | intptr_t value); | 171 | intptr_t value); |
106 | int get_replaygain_mode(bool have_track_gain, bool have_album_gain); | 172 | |
107 | void dsp_set_replaygain(void); | 173 | /* One-time startup init that must come before settings reset/apply */ |
108 | void dsp_set_crossfeed(bool enable); | 174 | void dsp_init(void); |
109 | void dsp_set_crossfeed_direct_gain(int gain); | 175 | |
110 | void dsp_set_crossfeed_cross_params(long lf_gain, long hf_gain, | 176 | #endif /* _DSP_H */ |
111 | long cutoff); | ||
112 | void dsp_set_eq(bool enable); | ||
113 | void dsp_set_eq_precut(int precut); | ||
114 | void dsp_set_eq_coefs(int band, int cutoff, int q, int gain); | ||
115 | void dsp_dither_enable(bool enable); | ||
116 | void dsp_timestretch_enable(bool enable); | ||
117 | bool dsp_timestretch_available(void); | ||
118 | void sound_set_pitch(int32_t r); | ||
119 | int32_t sound_get_pitch(void); | ||
120 | void dsp_set_timestretch(int32_t percent); | ||
121 | int32_t dsp_get_timestretch(void); | ||
122 | int dsp_callback(int msg, intptr_t param); | ||
123 | struct compressor_settings; | ||
124 | void dsp_set_compressor(const struct compressor_settings *settings); | ||
125 | |||
126 | #endif | ||