2 * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
4 * This file is part of MPlayer.
6 * MPlayer is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * MPlayer is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include "libavcodec/avcodec.h"
29 #include "libavutil/rational.h"
31 // Data for specific instances of this filter
32 typedef struct af_resample_s
{
33 struct AVResampleContext
*avrctx
;
45 // Initialization and runtime control
46 static int control(struct af_instance_s
* af
, int cmd
, void* arg
)
48 af_resample_t
* s
= (af_resample_t
*)af
->setup
;
49 af_data_t
*data
= (af_data_t
*)arg
;
50 int out_rate
, test_output_res
; // helpers for checking input format
53 case AF_CONTROL_REINIT
:
54 if((af
->data
->rate
== data
->rate
) || (af
->data
->rate
== 0))
57 af
->data
->nch
= data
->nch
;
58 if (af
->data
->nch
> AF_NCH
) af
->data
->nch
= AF_NCH
;
59 af
->data
->format
= AF_FORMAT_S16_NE
;
61 af
->mul
= (double)af
->data
->rate
/ data
->rate
;
62 af
->delay
= af
->data
->nch
* s
->filter_length
/ min(af
->mul
, 1); // *bps*.5
64 if(s
->avrctx
) av_resample_close(s
->avrctx
);
65 s
->avrctx
= av_resample_init(af
->data
->rate
, /*in_rate*/data
->rate
, s
->filter_length
, s
->phase_shift
, s
->linear
, s
->cutoff
);
67 // hack to make af_test_output ignore the samplerate change
68 out_rate
= af
->data
->rate
;
69 af
->data
->rate
= data
->rate
;
70 test_output_res
= af_test_output(af
, (af_data_t
*)arg
);
71 af
->data
->rate
= out_rate
;
72 return test_output_res
;
73 case AF_CONTROL_COMMAND_LINE
:{
75 sscanf((char*)arg
,"%d:%d:%d:%d:%lf", &af
->data
->rate
, &s
->filter_length
, &s
->linear
, &s
->phase_shift
, &s
->cutoff
);
76 if(s
->cutoff
<= 0.0) s
->cutoff
= max(1.0 - 6.5/(s
->filter_length
+8), 0.80);
79 case AF_CONTROL_RESAMPLE_RATE
| AF_CONTROL_SET
:
80 af
->data
->rate
= *(int*)arg
;
87 static void uninit(struct af_instance_s
* af
)
90 free(af
->data
->audio
);
94 af_resample_t
*s
= af
->setup
;
95 if(s
->avrctx
) av_resample_close(s
->avrctx
);
96 for (i
=0; i
< AF_NCH
; i
++)
102 // Filter data through filter
103 static af_data_t
* play(struct af_instance_s
* af
, af_data_t
* data
)
105 af_resample_t
*s
= af
->setup
;
106 int i
, j
, consumed
, ret
;
107 int16_t *in
= (int16_t*)data
->audio
;
109 int chans
= data
->nch
;
110 int in_len
= data
->len
/(2*chans
);
111 int out_len
= in_len
* af
->mul
+ 10;
112 int16_t tmp
[AF_NCH
][out_len
];
114 if(AF_OK
!= RESIZE_LOCAL_BUFFER(af
,data
))
117 out
= (int16_t*)af
->data
->audio
;
119 out_len
= min(out_len
, af
->data
->len
/(2*chans
));
121 if(s
->in_alloc
< in_len
+ s
->index
){
122 s
->in_alloc
= in_len
+ s
->index
;
123 for(i
=0; i
<chans
; i
++){
124 s
->in
[i
]= realloc(s
->in
[i
], s
->in_alloc
*sizeof(int16_t));
129 memcpy(&s
->in
[0][s
->index
], in
, in_len
* sizeof(int16_t));
131 for(j
=0; j
<in_len
; j
++){
132 s
->in
[0][j
+ s
->index
]= *(in
++);
133 s
->in
[1][j
+ s
->index
]= *(in
++);
136 for(j
=0; j
<in_len
; j
++){
137 for(i
=0; i
<chans
; i
++){
138 s
->in
[i
][j
+ s
->index
]= *(in
++);
144 for(i
=0; i
<chans
; i
++){
145 ret
= av_resample(s
->avrctx
, tmp
[i
], s
->in
[i
], &consumed
, in_len
, out_len
, i
+1 == chans
);
149 s
->index
= in_len
- consumed
;
150 for(i
=0; i
<chans
; i
++){
151 memmove(s
->in
[i
], s
->in
[i
] + consumed
, s
->index
*sizeof(int16_t));
155 memcpy(out
, tmp
[0], out_len
*sizeof(int16_t));
157 for(j
=0; j
<out_len
; j
++){
162 for(j
=0; j
<out_len
; j
++){
163 for(i
=0; i
<chans
; i
++){
169 data
->audio
= af
->data
->audio
;
170 data
->len
= out_len
*chans
*2;
171 data
->rate
= af
->data
->rate
;
175 static int af_open(af_instance_t
* af
){
176 af_resample_t
*s
= calloc(1,sizeof(af_resample_t
));
181 af
->data
=calloc(1,sizeof(af_data_t
));
182 s
->filter_length
= 16;
183 s
->cutoff
= max(1.0 - 6.5/(s
->filter_length
+8), 0.80);
185 // s->setup = RSMP_INT | FREQ_SLOPPY;
190 af_info_t af_info_lavcresample
= {
191 "Sample frequency conversion using libavcodec",
193 "Michael Niedermayer",