LMMS
Loading...
Searching...
No Matches
BandLimitedWave.h
Go to the documentation of this file.
1/*
2 * BandLimitedWave.h - helper functions for band-limited
3 * waveform generation
4 *
5 * Copyright (c) 2014 Vesa Kivimäki <contact/dot/diizy/at/nbl/dot/fi>
6 *
7 * This file is part of LMMS - https://lmms.io
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public
20 * License along with this program (see COPYING); if not, write to the
21 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301 USA.
23 *
24 */
25
26#ifndef LMMS_BANDLIMITEDWAVE_H
27#define LMMS_BANDLIMITEDWAVE_H
28
29class QDataStream;
30class QString;
31
32#include "lmms_export.h"
33#include "interpolation.h"
34#include "LmmsTypes.h"
35#include "lmms_math.h"
36#include "Engine.h"
37#include "AudioEngine.h"
38
39namespace lmms
40{
41
42constexpr int MAXLEN = 11;
43constexpr int MIPMAPSIZE = 2 << ( MAXLEN + 1 );
44constexpr int MIPMAPSIZE3 = 3 << ( MAXLEN + 1 );
45constexpr int MAXTBL = 23;
46constexpr int MINTLEN = 2 << 0;
47constexpr int MAXTLEN = 3 << MAXLEN;
48
49// table for table sizes
50const int TLENS[MAXTBL+1] = { 2 << 0, 3 << 0, 2 << 1, 3 << 1,
51 2 << 2, 3 << 2, 2 << 3, 3 << 3,
52 2 << 4, 3 << 4, 2 << 5, 3 << 5,
53 2 << 6, 3 << 6, 2 << 7, 3 << 7,
54 2 << 8, 3 << 8, 2 << 9, 3 << 9,
55 2 << 10, 3 << 10, 2 << 11, 3 << 11 };
56
58{
59public:
60 inline sample_t sampleAt(int table, int ph)
61 {
62 if (table % 2 == 0) { return m_data[TLENS[table] + ph]; }
63 else
64 {
65 return m_data3[TLENS[table] + ph];
66 }
67 }
68 inline void setSampleAt(int table, int ph, sample_t sample)
69 {
70 if (table % 2 == 0) { m_data[TLENS[table] + ph] = sample; }
71 else
72 {
73 m_data3[TLENS[table] + ph] = sample;
74 }
75 }
76
77private:
80};
81
82QDataStream& operator<< ( QDataStream &out, WaveMipMap &waveMipMap );
83
84
85QDataStream& operator>> ( QDataStream &in, WaveMipMap &waveMipMap );
86
87
88
89class LMMS_EXPORT BandLimitedWave
90{
91public:
92 enum class Waveform
93 {
94 BLSaw,
95 BLSquare,
96 BLTriangle,
97 BLMoog,
99 };
100 constexpr static auto NumWaveforms = static_cast<std::size_t>(Waveform::Count);
101
102 BandLimitedWave() = default;
103 virtual ~BandLimitedWave() = default;
104
108 static inline float freqToLen( float f )
109 {
110 return freqToLen( f, Engine::audioEngine()->outputSampleRate() );
111 }
112
115 static inline float freqToLen( float f, sample_rate_t sr )
116 {
117 return static_cast<float>( sr ) / f;
118 }
119
121 static inline float pdToLen( float pd )
122 {
123 return 1.0f / pd;
124 }
125
131 static inline sample_t oscillate( float _ph, float _wavelen, Waveform _wave )
132 {
133 // get the next higher tlen
134 int t = 0;
135 while( t < MAXTBL && _wavelen >= TLENS[t+1] ) { t++; }
136
137 int tlen = TLENS[t];
138 const float ph = fraction( _ph );
139 const float lookupf = ph * static_cast<float>( tlen );
140 int lookup = static_cast<int>( lookupf );
141 const float ip = fraction( lookupf );
142
143 const sample_t s1 = s_waveforms[ static_cast<std::size_t>(_wave) ].sampleAt( t, lookup );
144 const sample_t s2 = s_waveforms[ static_cast<std::size_t>(_wave) ].sampleAt( t, ( lookup + 1 ) % tlen );
145
146 const int lm = lookup == 0 ? tlen - 1 : lookup - 1;
147 const sample_t s0 = s_waveforms[ static_cast<std::size_t>(_wave) ].sampleAt( t, lm );
148 const sample_t s3 = s_waveforms[ static_cast<std::size_t>(_wave) ].sampleAt( t, ( lookup + 2 ) % tlen );
149 const sample_t sr = optimal4pInterpolate( s0, s1, s2, s3, ip );
150
151 return sr;
152
153 /*
154 lookup = lookup << 1;
155 tlen = tlen << 1;
156 t += 1;
157 const sample_t s3 = s_waveforms[ static_cast<std::size_t>(_wave) ].sampleAt( t, lookup );
158 const sample_t s4 = s_waveforms[ static_cast<std::size_t>(_wave) ].sampleAt( t, ( lookup + 1 ) % tlen );
159 const sample_t s34 = std::lerp(s3, s4, ip);
160
161 const float ip2 = ( ( tlen - _wavelen ) / tlen - 0.5 ) * 2.0;
162
163 return std::lerp(s12, s34, ip2);
164 */
165 };
166
167
168 static void generateWaves();
169
170 static bool s_wavesGenerated;
171
172 static std::array<WaveMipMap, NumWaveforms> s_waveforms;
173
174 static QString s_wavetableDir;
175};
176
177} // namespace lmms
178
179#endif // LMMS_BANDLIMITEDWAVE_H
static QString s_wavetableDir
Definition BandLimitedWave.h:174
static sample_t oscillate(float _ph, float _wavelen, Waveform _wave)
This method provides interpolated samples of bandlimited waveforms.
Definition BandLimitedWave.h:131
Waveform
Definition BandLimitedWave.h:93
@ Count
Definition BandLimitedWave.h:98
static float freqToLen(float f)
This method converts frequency to wavelength. The oscillate function takes wavelength as argument so ...
Definition BandLimitedWave.h:108
static float freqToLen(float f, sample_rate_t sr)
This method converts frequency to wavelength, but you can use any custom sample rate with it.
Definition BandLimitedWave.h:115
static constexpr auto NumWaveforms
Definition BandLimitedWave.h:100
static std::array< WaveMipMap, NumWaveforms > s_waveforms
Definition BandLimitedWave.h:172
virtual ~BandLimitedWave()=default
static float pdToLen(float pd)
This method converts phase delta to wavelength. It assumes a phase scale of 0 to 1.
Definition BandLimitedWave.h:121
static bool s_wavesGenerated
Definition BandLimitedWave.h:170
static AudioEngine * audioEngine()
Definition Engine.h:59
struct huft * t
Definition inflate.c:943
unsigned f
Definition inflate.c:1572
float in
Definition lilv_test.c:1460
float out
Definition lilv_test.c:1461
Definition AudioAlsa.cpp:35
constexpr int MIPMAPSIZE3
Definition BandLimitedWave.h:44
constexpr int MIPMAPSIZE
Definition BandLimitedWave.h:43
std::uint32_t sample_rate_t
Definition LmmsTypes.h:42
float sample_t
Definition LmmsTypes.h:39
constexpr int MAXTLEN
Definition BandLimitedWave.h:47
QDataStream & operator>>(QDataStream &in, WaveMipMap &waveMipMap)
Definition BandLimitedWave.cpp:50
QDataStream & operator<<(QDataStream &out, WaveMipMap &waveMipMap)
Definition BandLimitedWave.cpp:38
float optimal4pInterpolate(float v0, float v1, float v2, float v3, float x)
Definition interpolation.h:100
constexpr int MAXTBL
Definition BandLimitedWave.h:45
@ Count
Definition Sfxr.h:43
constexpr int MINTLEN
Definition BandLimitedWave.h:46
constexpr int MAXLEN
Definition BandLimitedWave.h:42
auto fraction(std::floating_point auto x) noexcept
Returns the fractional part of a float, a value between -1.0f and 1.0f.
Definition lmms_math.h:63
const int TLENS[MAXTBL+1]
Definition BandLimitedWave.h:50
Definition BandLimitedWave.h:58
sample_t m_data[MIPMAPSIZE]
Definition BandLimitedWave.h:78
sample_t m_data3[MIPMAPSIZE3]
Definition BandLimitedWave.h:79
void setSampleAt(int table, int ph, sample_t sample)
Definition BandLimitedWave.h:68
sample_t sampleAt(int table, int ph)
Definition BandLimitedWave.h:60
signed int sample
Definition tap_dynamics_m.c:41