1 // Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
12 #ifdef USE_LIBAVCODEC_SO
13 #include <ffmpeg/avcodec.h>
14 #include <ffmpeg/rational.h>
22 int64_t ff_gcd(int64_t a
, int64_t b
);
24 // Data for specific instances of this filter
25 typedef struct af_resample_s
{
26 struct AVResampleContext
*avrctx
;
38 // Initialization and runtime control
39 static int control(struct af_instance_s
* af
, int cmd
, void* arg
)
41 af_resample_t
* s
= (af_resample_t
*)af
->setup
;
42 af_data_t
*data
= (af_data_t
*)arg
;
43 int out_rate
, test_output_res
; // helpers for checking input format
46 case AF_CONTROL_REINIT
:
47 if((af
->data
->rate
== data
->rate
) || (af
->data
->rate
== 0))
50 af
->data
->nch
= data
->nch
;
51 if (af
->data
->nch
> CHANS
) af
->data
->nch
= CHANS
;
52 af
->data
->format
= AF_FORMAT_S16_NE
;
54 af
->mul
.n
= af
->data
->rate
;
55 af
->mul
.d
= data
->rate
;
56 af_frac_cancel(&af
->mul
);
57 af
->delay
= 500*s
->filter_length
/(double)min(af
->data
->rate
, data
->rate
);
59 if(s
->avrctx
) av_resample_close(s
->avrctx
);
60 s
->avrctx
= av_resample_init(af
->mul
.n
, /*in_rate*/af
->mul
.d
, s
->filter_length
, s
->phase_shift
, s
->linear
, s
->cutoff
);
62 // hack to make af_test_output ignore the samplerate change
63 out_rate
= af
->data
->rate
;
64 af
->data
->rate
= data
->rate
;
65 test_output_res
= af_test_output(af
, (af_data_t
*)arg
);
66 af
->data
->rate
= out_rate
;
67 return test_output_res
;
68 case AF_CONTROL_COMMAND_LINE
:{
69 sscanf((char*)arg
,"%d:%d:%d:%d:%lf", &af
->data
->rate
, &s
->filter_length
, &s
->linear
, &s
->phase_shift
, &s
->cutoff
);
70 if(s
->cutoff
<= 0.0) s
->cutoff
= max(1.0 - 1.0/s
->filter_length
, 0.80);
73 case AF_CONTROL_RESAMPLE_RATE
| AF_CONTROL_SET
:
74 af
->data
->rate
= *(int*)arg
;
81 static void uninit(struct af_instance_s
* af
)
86 af_resample_t
*s
= af
->setup
;
87 if(s
->avrctx
) av_resample_close(s
->avrctx
);
92 // Filter data through filter
93 static af_data_t
* play(struct af_instance_s
* af
, af_data_t
* data
)
95 af_resample_t
*s
= af
->setup
;
96 int i
, j
, consumed
, ret
;
97 int16_t *in
= (int16_t*)data
->audio
;
99 int chans
= data
->nch
;
100 int in_len
= data
->len
/(2*chans
);
101 int out_len
= (in_len
*af
->mul
.n
) / af
->mul
.d
+ 10;
102 int16_t tmp
[CHANS
][out_len
];
104 if(AF_OK
!= RESIZE_LOCAL_BUFFER(af
,data
))
107 out
= (int16_t*)af
->data
->audio
;
109 out_len
= min(out_len
, af
->data
->len
/(2*chans
));
111 if(s
->in_alloc
< in_len
+ s
->index
){
112 s
->in_alloc
= in_len
+ s
->index
;
113 for(i
=0; i
<chans
; i
++){
114 s
->in
[i
]= realloc(s
->in
[i
], s
->in_alloc
*sizeof(int16_t)); //FIXME free this maybe ;)
119 memcpy(&s
->in
[0][s
->index
], in
, in_len
* sizeof(int16_t));
121 for(j
=0; j
<in_len
; j
++){
122 s
->in
[0][j
+ s
->index
]= *(in
++);
123 s
->in
[1][j
+ s
->index
]= *(in
++);
126 for(j
=0; j
<in_len
; j
++){
127 for(i
=0; i
<chans
; i
++){
128 s
->in
[i
][j
+ s
->index
]= *(in
++);
134 for(i
=0; i
<chans
; i
++){
135 ret
= av_resample(s
->avrctx
, tmp
[i
], s
->in
[i
], &consumed
, in_len
, out_len
, i
+1 == chans
);
139 s
->index
= in_len
- consumed
;
140 for(i
=0; i
<chans
; i
++){
141 memmove(s
->in
[i
], s
->in
[i
] + consumed
, s
->index
*sizeof(int16_t));
145 memcpy(out
, tmp
[0], out_len
*sizeof(int16_t));
147 for(j
=0; j
<out_len
; j
++){
152 for(j
=0; j
<out_len
; j
++){
153 for(i
=0; i
<chans
; i
++){
159 data
->audio
= af
->data
->audio
;
160 data
->len
= out_len
*chans
*2;
161 data
->rate
= af
->data
->rate
;
165 static int open(af_instance_t
* af
){
166 af_resample_t
*s
= calloc(1,sizeof(af_resample_t
));
172 af
->data
=calloc(1,sizeof(af_data_t
));
173 s
->filter_length
= 16;
174 s
->cutoff
= max(1.0 - 1.0/s
->filter_length
, 0.80);
176 // s->setup = RSMP_INT | FREQ_SLOPPY;
181 af_info_t af_info_lavcresample
= {
182 "Sample frequency conversion using libavcodec",
184 "Michael Niedermayer",