1 // Copyright (C) 2008-2011 David Sugar, Tycho Softworks.
2 //
3 // This file is part of GNU Bayonne.
4 //
5 // GNU Bayonne is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // GNU Bayonne is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with GNU Bayonne. If not, see <http://www.gnu.org/licenses/>.
17
18 #include <config.h>
19 #include <ucommon/ucommon.h>
20 #include <ucommon/export.h>
22
24 using namespace UCOMMON_NAMESPACE;
25
26 Audio::resample::resample(Audio::rate_t div, Audio::rate_t mul)
27 {
28 bool common = true;
29 while(common) {
30 common = false;
31
32 while(!(mul & 0x01) && !(div & 0x01)) {
33 mul = (Audio::rate_t)(mul >> 1);
34 div = (Audio::rate_t)(div >> 1);
35 common = true;
36 }
37
38 while(!(mul % 3) && !(div % 3)) {
39 mul = (Audio::rate_t)(mul / 3);
40 div = (Audio::rate_t)(div / 3);
41 common = true;
42 }
43
44 while(!(mul % 5) && !(div %5)) {
45 mul = (rate_t)(mul / 5);
46 div = (rate_t)(div / 5);
47 common = true;
48 }
49 }
50
51
52 mfact = (unsigned)mul;
53 dfact = (unsigned)div;
54
55 max = mfact;
56 if(dfact > mfact)
57 max = dfact;
58
59 ++max;
60 buffer = new Audio::sample_t[max];
61 ppos = gpos = 0;
62 memset(buffer, 0, max * 2);
63 last = 0;
64 }
65
66 Audio::resample::~resample()
67 {
68 delete[] buffer;
69 }
70
71 size_t Audio::resample::estimate(size_t count)
72 {
73 count *= mfact;
74 count += (mfact - 1);
75 return (count / dfact) + 1;
76 }
77
78 size_t Audio::resample::process(linear_t from, linear_t dest, size_t count)
79 {
80 size_t saved = 0;
81 sample_t diff, current;
82 unsigned pos;
83 unsigned dpos;
84
85 while(count--) {
86 current = *(from++);
87 diff = (current - last) / mfact;
88 pos = mfact;
89 while(pos--) {
90 last += diff;
91 buffer[ppos++] = current;
92 if(ppos >= max)
93 ppos = 0;
94
95 if(gpos < ppos)
96 dpos = ppos - gpos;
97 else
98 dpos = max - (gpos - ppos);
99 if(dpos >= dfact) {
100 *(dest++) = buffer[gpos];
101 ++saved;
102 gpos += dfact;
103 if(gpos >= max)
104 gpos = gpos - max;
105 }
106 }
107 last = current;
108 }
109 return saved;
110 }
#define BAYONNE_NAMESPACE
GNU Bayonne library namespace.