Interpolation: first working version with sinc
[ardour.git] / libs / ardour / interpolation.cc
1 #include <stdint.h>
2
3 #include "ardour/interpolation.h"
4
5 using namespace ARDOUR;
6
7 Interpolation::Interpolation()  : _speed (1.0L), state (0)
8 {
9 }
10
11 Interpolation::~Interpolation() 
12 {
13         state = src_delete (state);
14 }
15
16 void
17 Interpolation::set_speed (double new_speed)
18
19         _speed = new_speed; 
20         src_set_ratio (state, 1.0/_speed); 
21 }
22
23 void
24 Interpolation::reset_state ()
25 {
26         if (state) {
27                 src_reset (state);
28         } else {
29                 state = src_new (SRC_LINEAR, 1, &error);
30         }
31 }
32
33 void
34 Interpolation::add_channel_to (int input_buffer_size, int output_buffer_size) 
35 {
36         SRC_DATA newdata;
37         
38         /* Set up sample rate converter info. */
39         newdata.end_of_input = 0 ; 
40
41         newdata.input_frames  = input_buffer_size;
42         newdata.output_frames = output_buffer_size;
43
44         newdata.input_frames_used = 0 ;
45         newdata.output_frames_gen = 0 ;
46
47         newdata.src_ratio = 1.0/_speed;
48         
49         data.push_back (newdata);
50         
51         reset_state ();
52 }
53
54 void
55 Interpolation::remove_channel_from () 
56 {
57         data.pop_back ();
58         reset_state ();
59 }
60
61 nframes_t
62 Interpolation::interpolate (int channel, nframes_t nframes, Sample *input, Sample *output)
63 {       
64         data[channel].data_in       = input;
65         data[channel].data_out      = output;
66         
67         data[channel].input_frames = nframes * _speed;
68         data[channel].output_frames = nframes;
69         data[channel].src_ratio     = 1.0/_speed; 
70
71         if ((error = src_process (state, &data[channel]))) {    
72                 printf ("\nError : %s\n\n", src_strerror (error));
73                 exit (1);
74         }
75
76         return data[channel].input_frames_used;
77 }