blob: 5268a66f2848ead08706655a8a095c24134114ab [file] [log] [blame]
Seppo Ingalsuo6a274832017-06-07 14:17:55 +03001/*
2 * Copyright (c) 2017, Intel Corporation
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the Intel Corporation nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Author: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
29 *
30 */
31
Seppo Ingalsuoe8afa162018-03-08 16:22:17 +020032#ifndef SRC_H
33#define SRC_H
Seppo Ingalsuo6a274832017-06-07 14:17:55 +030034
Seppo Ingalsuo28fafc12017-10-05 18:57:37 +030035struct src_param {
Seppo Ingalsuo6a274832017-06-07 14:17:55 +030036 int fir_s1;
37 int fir_s2;
38 int out_s1;
39 int out_s2;
Seppo Ingalsuo28fafc12017-10-05 18:57:37 +030040 int sbuf_length;
Seppo Ingalsuo4b007cb2017-10-20 18:45:30 +030041 int src_multich;
Seppo Ingalsuo6a274832017-06-07 14:17:55 +030042 int total;
Seppo Ingalsuocb3a64d2017-09-06 15:16:12 +030043 int blk_in;
44 int blk_out;
45 int stage1_times;
46 int stage2_times;
Seppo Ingalsuo28fafc12017-10-05 18:57:37 +030047 int stage1_times_max;
48 int stage2_times_max;
Seppo Ingalsuocb3a64d2017-09-06 15:16:12 +030049 int idx_in;
50 int idx_out;
Seppo Ingalsuo4b007cb2017-10-20 18:45:30 +030051 int nch;
Seppo Ingalsuo6a274832017-06-07 14:17:55 +030052};
53
54struct src_stage {
55 const int idm;
56 const int odm;
57 const int num_of_subfilters;
58 const int subfilter_length;
59 const int filter_length;
60 const int blk_in;
61 const int blk_out;
62 const int halfband;
63 const int shift;
Seppo Ingalsuod7f18632017-09-22 16:08:45 +030064 const void *coefs; /* Can be int16_t or int32_t depending on config */
Seppo Ingalsuo6a274832017-06-07 14:17:55 +030065};
66
67struct src_state {
Seppo Ingalsuoe8afa162018-03-08 16:22:17 +020068 int fir_delay_size; /* samples */
69 int out_delay_size; /* samples */
Seppo Ingalsuo6a274832017-06-07 14:17:55 +030070 int32_t *fir_delay;
71 int32_t *out_delay;
Seppo Ingalsuoe8afa162018-03-08 16:22:17 +020072 int32_t *fir_wp;
73 int32_t *out_rp;
Seppo Ingalsuo6a274832017-06-07 14:17:55 +030074};
75
76struct polyphase_src {
Seppo Ingalsuo6a274832017-06-07 14:17:55 +030077 int number_of_stages;
Seppo Ingalsuo6a274832017-06-07 14:17:55 +030078 struct src_stage *stage1;
79 struct src_stage *stage2;
80 struct src_state state1;
81 struct src_state state2;
82};
83
84struct src_stage_prm {
Seppo Ingalsuo4b007cb2017-10-20 18:45:30 +030085 int nch;
Seppo Ingalsuo6a274832017-06-07 14:17:55 +030086 int times;
87 int32_t *x_rptr;
88 int32_t *x_end_addr;
89 size_t x_size;
Seppo Ingalsuo6a274832017-06-07 14:17:55 +030090 int32_t *y_wptr;
Seppo Ingalsuoe8afa162018-03-08 16:22:17 +020091 int32_t *y_addr;
Seppo Ingalsuo6a274832017-06-07 14:17:55 +030092 int32_t *y_end_addr;
93 size_t y_size;
Seppo Ingalsuo6a274832017-06-07 14:17:55 +030094 struct src_state *state;
95 struct src_stage *stage;
96};
97
Seppo Ingalsuo28fafc12017-10-05 18:57:37 +030098static inline void src_circ_inc_wrap(int32_t **ptr, int32_t *end, size_t size)
99{
100 if (*ptr >= end)
Seppo Ingalsuoe8afa162018-03-08 16:22:17 +0200101 *ptr = (int32_t *)((size_t)*ptr - size);
Seppo Ingalsuo28fafc12017-10-05 18:57:37 +0300102}
103
104static inline void src_circ_dec_wrap(int32_t **ptr, int32_t *addr, size_t size)
105{
106 if (*ptr < addr)
Seppo Ingalsuoe8afa162018-03-08 16:22:17 +0200107 *ptr = (int32_t *)((size_t)*ptr + size);
Seppo Ingalsuo28fafc12017-10-05 18:57:37 +0300108}
109
Seppo Ingalsuo6a274832017-06-07 14:17:55 +0300110void src_polyphase_reset(struct polyphase_src *src);
111
Seppo Ingalsuo28fafc12017-10-05 18:57:37 +0300112int src_polyphase_init(struct polyphase_src *src, struct src_param *p,
Seppo Ingalsuo2a382e92017-09-28 20:06:45 +0300113 int32_t *delay_lines_start);
Seppo Ingalsuo6a274832017-06-07 14:17:55 +0300114
Seppo Ingalsuo4a006912017-06-28 19:25:51 +0300115int src_polyphase(struct polyphase_src *src, int32_t x[], int32_t y[],
116 int n_in);
Seppo Ingalsuo6a274832017-06-07 14:17:55 +0300117
118void src_polyphase_stage_cir(struct src_stage_prm *s);
119
Seppo Ingalsuo887628a2017-09-14 16:00:05 +0300120void src_polyphase_stage_cir_s24(struct src_stage_prm *s);
121
Seppo Ingalsuo28fafc12017-10-05 18:57:37 +0300122int src_buffer_lengths(struct src_param *p, int fs_in, int fs_out, int nch,
123 int frames, int frames_is_for_source);
Seppo Ingalsuo6a274832017-06-07 14:17:55 +0300124
Seppo Ingalsuo4a006912017-06-28 19:25:51 +0300125int32_t src_input_rates(void);
Seppo Ingalsuo6a274832017-06-07 14:17:55 +0300126
Seppo Ingalsuo4a006912017-06-28 19:25:51 +0300127int32_t src_output_rates(void);
Seppo Ingalsuo6a274832017-06-07 14:17:55 +0300128
Seppo Ingalsuo28fafc12017-10-05 18:57:37 +0300129int src_ceil_divide(int a, int b);
130
Seppo Ingalsuo6a274832017-06-07 14:17:55 +0300131#endif