77
88use std:: marker:: PhantomData ;
99
10- use rubato:: VecResampler ;
1110use symphonia:: core:: audio:: conv:: { FromSample , IntoSample } ;
1211use symphonia:: core:: audio:: sample:: Sample ;
13- use symphonia:: core:: audio:: { Audio , AudioBuffer , AudioMut , AudioSpec , GenericAudioBufferRef } ;
12+ use symphonia:: core:: audio:: { Audio , AudioBuffer , AudioSpec , GenericAudioBufferRef } ;
13+
14+ use rubato:: Resampler as _;
1415
1516pub struct Resampler < T > {
16- resampler : rubato:: FftFixedIn < f32 > ,
17+ resampler : rubato:: Fft < f32 > ,
1718 buf_in : AudioBuffer < f32 > ,
1819 buf_out : AudioBuffer < f32 > ,
1920 chunk_size : usize ,
@@ -43,22 +44,11 @@ where
4344
4445 // Get slices to the required regions of the input and output buffers.
4546 let ( read, _) = {
46- let mut slices_in: smallvec:: SmallVec < [ & [ f32 ] ; 8 ] > = Default :: default ( ) ;
47- let mut slices_out: smallvec:: SmallVec < [ & mut [ f32 ] ; 8 ] > = Default :: default ( ) ;
48-
49- for plane in self . buf_in . iter_planes ( ) {
50- slices_in. push ( & plane[ ..self . chunk_size ] ) ;
51- }
52-
53- for plane in self . buf_out . iter_planes_mut ( ) {
54- slices_out. push ( & mut plane[ begin..] ) ;
55- }
56-
5747 // Resample a chunk.
5848 rubato:: Resampler :: process_into_buffer (
5949 & mut self . resampler ,
60- & slices_in ,
61- & mut slices_out ,
50+ & AudioBufferAdapter ( & self . buf_in ) ,
51+ & mut AudioBufferAdapterMut ( & mut self . buf_out ) ,
6252 None ,
6353 )
6454 . unwrap ( )
@@ -80,12 +70,13 @@ where
8070 T : Sample + FromSample < f32 > + IntoSample < f32 > ,
8171{
8272 pub fn new ( spec_in : & AudioSpec , out_sample_rate : u32 , chunk_size : usize ) -> Self {
83- let resampler = rubato:: FftFixedIn :: < f32 > :: new (
73+ let resampler = rubato:: Fft :: < f32 > :: new (
8474 spec_in. rate ( ) as usize ,
8575 out_sample_rate as usize ,
8676 chunk_size,
87- 2 ,
77+ 1 ,
8878 spec_in. channels ( ) . count ( ) ,
79+ rubato:: FixedSync :: Input ,
8980 )
9081 . unwrap ( ) ;
9182
@@ -132,3 +123,55 @@ where
132123 self . resample_inner ( dst)
133124 }
134125}
126+
127+ // Implementing adapter interface for Symphonia's AudioBuffer. Since both the adapter traits and
128+ // audio buffers are foreign types, a new-type is used.
129+
130+ struct AudioBufferAdapter < ' a , S : Sample > ( & ' a AudioBuffer < S > ) ;
131+
132+ unsafe impl < ' a , T > rubato:: audioadapter:: Adapter < ' a , T > for AudioBufferAdapter < ' a , T >
133+ where
134+ T : Sample ,
135+ {
136+ unsafe fn read_sample_unchecked ( & self , channel : usize , frame : usize ) -> T {
137+ self . 0 [ channel] [ frame]
138+ }
139+
140+ fn channels ( & self ) -> usize {
141+ self . 0 . num_planes ( )
142+ }
143+
144+ fn frames ( & self ) -> usize {
145+ self . 0 . frames ( )
146+ }
147+ }
148+
149+ struct AudioBufferAdapterMut < ' a , S : Sample > ( & ' a mut AudioBuffer < S > ) ;
150+
151+ unsafe impl < ' a , T > rubato:: audioadapter:: Adapter < ' a , T > for AudioBufferAdapterMut < ' a , T >
152+ where
153+ T : Sample ,
154+ {
155+ unsafe fn read_sample_unchecked ( & self , channel : usize , frame : usize ) -> T {
156+ self . 0 [ channel] [ frame]
157+ }
158+
159+ fn channels ( & self ) -> usize {
160+ self . 0 . num_planes ( )
161+ }
162+
163+ fn frames ( & self ) -> usize {
164+ self . 0 . frames ( )
165+ }
166+ }
167+
168+ unsafe impl < ' a , T > rubato:: audioadapter:: AdapterMut < ' a , T > for AudioBufferAdapterMut < ' a , T >
169+ where
170+ T : Sample ,
171+ {
172+ unsafe fn write_sample_unchecked ( & mut self , channel : usize , frame : usize , value : & T ) -> bool {
173+ self . 0 [ channel] [ frame] = * value;
174+ // No sample format conversion was performed.
175+ false
176+ }
177+ }
0 commit comments