2 * Copyright 2010-2014 Haiku, inc.
3 * Distributed under the terms of the MIT Licence.
5 * Author: Adrien Destugues <pulkomandy@pulkomandy.tk>
9 #include "Interpolate.h"
13 #include <MediaDefs.h>
15 #include "MixerDebug.h"
18 /*! Resampling class doing linear interpolation.
22 template<typename inType
, typename outType
, int gnum
, int gden
, int offset
,
23 int32 min
, int32 max
> static void
24 kernel(Resampler
* object
, const void *_src
, int32 srcSampleOffset
,
25 int32 srcSampleCount
, void *_dest
, int32 destSampleOffset
,
26 int32 destSampleCount
, float _gain
)
28 register const char * src
= (const char *)_src
;
29 register char * dest
= (char *)_dest
;
30 register int32 count
= destSampleCount
;
31 register float gain
= _gain
* gnum
/ gden
;
33 if (srcSampleCount
== destSampleCount
) {
34 // optimized case for no resampling
36 float tmp
= *(const inType
*)src
* gain
+ offset
;
37 if (tmp
< min
) tmp
= min
;
38 if (tmp
> max
) tmp
= max
;
39 *(outType
*)dest
= (outType
)tmp
;
40 src
+= srcSampleOffset
;
41 dest
+= destSampleOffset
;
46 register float delta
= float(srcSampleCount
) / float(destSampleCount
);
47 register float current
= 0.0f
;
48 float oldSample
= ((Interpolate
*)object
)->fOldSample
;
50 #define SRC *(const inType*)(src)
53 float tmp
= (gain
* (oldSample
+ (SRC
- oldSample
) * current
) + offset
);
54 if (tmp
< min
) tmp
= min
;
55 if (tmp
> max
) tmp
= max
;
56 *(outType
*)dest
= (outType
)tmp
;
58 dest
+= destSampleOffset
;
60 if (current
>= 1.0f
) {
62 current
= modf(current
, &ipart
);
64 src
+= srcSampleOffset
* (int)ipart
;
68 ((Interpolate
*)object
)->fOldSample
= oldSample
;
72 Interpolate::Interpolate(uint32 src_format
, uint32 dst_format
)
77 if (dst_format
== media_raw_audio_format::B_AUDIO_FLOAT
) {
79 case media_raw_audio_format::B_AUDIO_FLOAT
:
80 fFunc
= &kernel
<float, float, 1, 1, 0, -1, 1>;
82 case media_raw_audio_format::B_AUDIO_INT
:
83 fFunc
= &kernel
<int32
, float, 1, INT32_MAX
, 0, -1, 1>;
85 case media_raw_audio_format::B_AUDIO_SHORT
:
86 fFunc
= &kernel
<int16
, float, 1, INT16_MAX
, 0, -1, 1>;
88 case media_raw_audio_format::B_AUDIO_CHAR
:
89 fFunc
= &kernel
<int8
, float, 1, INT8_MAX
, 0, -1, 1>;
91 case media_raw_audio_format::B_AUDIO_UCHAR
:
92 fFunc
= &kernel
<uint8
, float, 2, UINT8_MAX
, -128, -1, 1>;
95 ERROR("Resampler::Resampler: unknown source format 0x%x\n",
101 if (src_format
== media_raw_audio_format::B_AUDIO_FLOAT
) {
102 switch (dst_format
) {
103 // float=>float already handled above
104 case media_raw_audio_format::B_AUDIO_INT
:
105 fFunc
= &kernel
<float, int32
, INT32_MAX
, 1, 0,
106 INT32_MIN
, INT32_MAX
>;
108 case media_raw_audio_format::B_AUDIO_SHORT
:
109 fFunc
= &kernel
<float, int16
, INT16_MAX
, 1, 0,
110 INT16_MIN
, INT16_MAX
>;
112 case media_raw_audio_format::B_AUDIO_CHAR
:
113 fFunc
= &kernel
<float, int8
, INT8_MAX
, 1, 0,
116 case media_raw_audio_format::B_AUDIO_UCHAR
:
117 fFunc
= &kernel
<float, uint8
, UINT8_MAX
, 2, 1,
121 ERROR("Resampler::Resampler: unknown destination format 0x%x\n",
127 ERROR("Resampler::Resampler: source or destination format must be "