History

initial import

(automatically generated log message)

Erik de Castro Lopo committed 22 years ago

Commit 361a104No parent (first commit)79 files · +36993 −-5Browse files

Showing the changes to src/src_linear.c (1 of 79 files). Show all

Unified · Split

src/src_linear.c+204−0
@@ -0,0 +1,204 @@
1+/*
2+** Copyright (C) 2002,2003 Erik de Castro Lopo <erikd@mega-nerd.com>
3+**
4+** This program is free software; you can redistribute it and/or modify
5+** it under the terms of the GNU General Public License as published by
6+** the Free Software Foundation; either version 2 of the License, or
7+** (at your option) any later version.
8+**
9+** This program is distributed in the hope that it will be useful,
10+** but WITHOUT ANY WARRANTY; without even the implied warranty of
11+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+** GNU General Public License for more details.
13+**
14+** You should have received a copy of the GNU General Public License
15+** along with this program; if not, write to the Free Software
16+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
17+*/
18+
19+#include <stdio.h>
20+#include <stdlib.h>
21+#include <string.h>
22+
23+#include "config.h"
24+#include "float_cast.h"
25+#include "common.h"
26+
27+static void linear_reset (SRC_PRIVATE *psrc) ;
28+
29+/*========================================================================================
30+*/
31+
32+#define LINEAR_MAGIC_MARKER MAKE_MAGIC ('l', 'i', 'n', 'e', 'a', 'r')
33+
34+#define SRC_DEBUG 0
35+
36+typedef struct
37+{ int linear_magic_marker ;
38+ int channels ;
39+ long in_count, in_used ;
40+ long out_count, out_gen ;
41+ float last_value [1] ;
42+} LINEAR_DATA ;
43+
44+/*----------------------------------------------------------------------------------------
45+*/
46+int
47+linear_process (SRC_PRIVATE *psrc, SRC_DATA *data)
48+{ LINEAR_DATA *linear ;
49+ double src_ratio, input_index ;
50+ int ch ;
51+
52+ if (psrc->private_data == NULL)
53+ return SRC_ERR_NO_PRIVATE ;
54+
55+ linear = (LINEAR_DATA*) psrc->private_data ;
56+
57+ linear->in_count = data->input_frames * linear->channels ;
58+ linear->out_count = data->output_frames * linear->channels ;
59+ linear->in_used = linear->out_gen = 0 ;
60+
61+ src_ratio = psrc->last_ratio ;
62+ input_index = psrc->last_position ;
63+
64+ /* Calculate samples before first sample in input array. */
65+ while (input_index < 1.0 && linear->out_gen < linear->out_count)
66+ {
67+ if (linear->in_used + linear->channels * input_index > linear->in_count)
68+ break ;
69+
70+ if (fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
71+ src_ratio = psrc->last_ratio + linear->out_gen * (data->src_ratio - psrc->last_ratio) / (linear->out_count - 1) ;
72+
73+ for (ch = 0 ; ch < linear->channels ; ch++)
74+ { data->data_out [linear->out_gen] = linear->last_value [ch] + input_index *
75+ (data->data_in [ch] - linear->last_value [ch]) ;
76+ linear->out_gen ++ ;
77+ } ;
78+
79+ /* Figure out the next index. */
80+ input_index += 1.0 / src_ratio ;
81+ } ;
82+
83+ linear->in_used += linear->channels * lrint (floor (input_index)) ;
84+ input_index -= floor (input_index) ;
85+
86+ /* Main processing loop. */
87+ while (linear->out_gen < linear->out_count && linear->in_used + linear->channels * input_index <= linear->in_count)
88+ {
89+ if (fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
90+ src_ratio = psrc->last_ratio + linear->out_gen * (data->src_ratio - psrc->last_ratio) / (linear->out_count - 1) ;
91+
92+ if (SRC_DEBUG && linear->in_used < linear->channels && input_index < 1.0)
93+ { printf ("Whoops!!!! in_used : %ld channels : %d input_index : %f\n", linear->in_used, linear->channels, input_index) ;
94+ exit (1) ;
95+ } ;
96+
97+ for (ch = 0 ; ch < linear->channels ; ch++)
98+ { data->data_out [linear->out_gen] = data->data_in [linear->in_used - linear->channels + ch] + input_index *
99+ (data->data_in [linear->in_used + ch] - data->data_in [linear->in_used - linear->channels + ch]) ;
100+ linear->out_gen ++ ;
101+ } ;
102+
103+ /* Figure out the next index. */
104+ input_index += 1.0 / src_ratio ;
105+
106+ linear->in_used += linear->channels * lrint (floor (input_index)) ;
107+ input_index -= floor (input_index) ;
108+ } ;
109+
110+ if (linear->in_used > linear->in_count)
111+ { input_index += linear->in_used - linear->in_count ;
112+ linear->in_used = linear->in_count ;
113+ } ;
114+
115+ psrc->last_position = input_index ;
116+
117+ if (linear->in_used > 0)
118+ for (ch = 0 ; ch < linear->channels ; ch++)
119+ linear->last_value [ch] = data->data_in [linear->in_used - linear->channels + ch] ;
120+
121+ /* Save current ratio rather then target ratio. */
122+ psrc->last_ratio = src_ratio ;
123+
124+ data->input_frames_used = linear->in_used / linear->channels ;
125+ data->output_frames_gen = linear->out_gen / linear->channels ;
126+
127+ return SRC_ERR_NO_ERROR ;
128+} /* linear_process */
129+
130+/*------------------------------------------------------------------------------
131+*/
132+
133+const char*
134+linear_get_name (int src_enum)
135+{
136+ if (src_enum == SRC_LINEAR)
137+ return "Linear Interpolator" ;
138+
139+ return NULL ;
140+} /* linear_get_name */
141+
142+const char*
143+linear_get_description (int src_enum)
144+{
145+ if (src_enum == SRC_LINEAR)
146+ return "Linear interpolator, very fast, poor quality." ;
147+
148+ return NULL ;
149+} /* linear_get_descrition */
150+
151+int
152+linear_set_converter (SRC_PRIVATE *psrc, int src_enum)
153+{ LINEAR_DATA *linear = NULL ;
154+
155+ if (src_enum != SRC_LINEAR)
156+ return SRC_ERR_BAD_CONVERTER ;
157+
158+ if (psrc->private_data != NULL)
159+ { linear = (LINEAR_DATA*) psrc->private_data ;
160+ if (linear->linear_magic_marker != LINEAR_MAGIC_MARKER)
161+ { free (psrc->private_data) ;
162+ psrc->private_data = NULL ;
163+ } ;
164+ } ;
165+
166+ if (psrc->private_data == NULL)
167+ { linear = calloc (1, sizeof (*linear) + psrc->channels * sizeof (float)) ;
168+ if (linear == NULL)
169+ return SRC_ERR_MALLOC_FAILED ;
170+ psrc->private_data = linear ;
171+ } ;
172+
173+ linear->linear_magic_marker = LINEAR_MAGIC_MARKER ;
174+ linear->channels = psrc->channels ;
175+
176+ psrc->process = linear_process ;
177+ psrc->reset = linear_reset ;
178+
179+ linear_reset (psrc) ;
180+
181+ return SRC_ERR_NO_ERROR ;
182+} /* linear_set_converter */
183+
184+/*===================================================================================
185+*/
186+
187+static void
188+linear_reset (SRC_PRIVATE *psrc)
189+{ LINEAR_DATA *linear = NULL ;
190+
191+ linear = (LINEAR_DATA*) psrc->private_data ;
192+ if (linear == NULL)
193+ return ;
194+
195+ memset (linear->last_value, 0, sizeof (linear->last_value [0]) * linear->channels) ;
196+} /* linear_reset */
197+/*
198+** Do not edit or modify anything in this comment block.
199+** The arch-tag line is a file identity tag for the GNU Arch
200+** revision control system.
201+**
202+** arch-tag: 7eac3103-3d84-45d3-8bbd-f409c2b2d1a9
203+*/
204+

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t