3rdparty/licenseReport: Add seperate LGPL checks
[haiku.git] / src / add-ons / media / media-add-ons / mixer / Interpolate.cpp
blob17bbbb21f2f83abfd88be5371e397bb6e7c37831
1 /*
2 * Copyright 2010-2014 Haiku, inc.
3 * Distributed under the terms of the MIT Licence.
5 * Author: Adrien Destugues <pulkomandy@pulkomandy.tk>
6 */
9 #include "Interpolate.h"
11 #include <cmath>
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
35 while (count--) {
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;
43 return;
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)
52 while (count--) {
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;
59 current += delta;
60 if (current >= 1.0f) {
61 double ipart;
62 current = modf(current, &ipart);
63 oldSample = SRC;
64 src += srcSampleOffset * (int)ipart;
68 ((Interpolate*)object)->fOldSample = oldSample;
72 Interpolate::Interpolate(uint32 src_format, uint32 dst_format)
74 Resampler(),
75 fOldSample(0)
77 if (dst_format == media_raw_audio_format::B_AUDIO_FLOAT) {
78 switch (src_format) {
79 case media_raw_audio_format::B_AUDIO_FLOAT:
80 fFunc = &kernel<float, float, 1, 1, 0, -1, 1>;
81 return;
82 case media_raw_audio_format::B_AUDIO_INT:
83 fFunc = &kernel<int32, float, 1, INT32_MAX, 0, -1, 1>;
84 return;
85 case media_raw_audio_format::B_AUDIO_SHORT:
86 fFunc = &kernel<int16, float, 1, INT16_MAX, 0, -1, 1>;
87 return;
88 case media_raw_audio_format::B_AUDIO_CHAR:
89 fFunc = &kernel<int8, float, 1, INT8_MAX, 0, -1, 1>;
90 return;
91 case media_raw_audio_format::B_AUDIO_UCHAR:
92 fFunc = &kernel<uint8, float, 2, UINT8_MAX, -128, -1, 1>;
93 return;
94 default:
95 ERROR("Resampler::Resampler: unknown source format 0x%x\n",
96 src_format);
97 return;
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>;
107 return;
108 case media_raw_audio_format::B_AUDIO_SHORT:
109 fFunc = &kernel<float, int16, INT16_MAX, 1, 0,
110 INT16_MIN, INT16_MAX>;
111 return;
112 case media_raw_audio_format::B_AUDIO_CHAR:
113 fFunc = &kernel<float, int8, INT8_MAX, 1, 0,
114 INT8_MIN, INT8_MAX>;
115 return;
116 case media_raw_audio_format::B_AUDIO_UCHAR:
117 fFunc = &kernel<float, uint8, UINT8_MAX, 2, 1,
118 0, UINT8_MAX>;
119 return;
120 default:
121 ERROR("Resampler::Resampler: unknown destination format 0x%x\n",
122 dst_format);
123 return;
127 ERROR("Resampler::Resampler: source or destination format must be "
128 "B_AUDIO_FLOAT\n");