35 #define STATUS if (Voice::mVerbosity >= 4) qDebug() << "Wave:" 36 #define MESSAGE if (Voice::mVerbosity >= 3) qDebug() << "Wave:" 37 #define WARNING if (Voice::mVerbosity >= 2) qWarning()<<"Wave: WARNING:" 38 #define ERROR if (Voice::mVerbosity >= 1) qCritical() << "Wave: ERROR:" 50 , mRepetitionFactor(1)
71 if (samplerate==0)
return;
75 double phaseleft = 2*stereo;
76 double phaseright = - 2*stereo;
78 double increment = frequency / samplerate;
80 for (
int i=0; i<N/2; ++i)
82 phaseleft += increment;
while (phaseleft>1) phaseleft--;
83 phaseright += increment;
while (phaseright>1) phaseright--;
84 amplitude = 32768.0*std::min(500*i,N/2-i)/N*2;
85 mSustainSample[2*i] = amplitude*(phaseleft < 0.5 ? 0.22 - phaseleft : phaseleft-0.72);
86 mSustainSample[2*i+1] = amplitude*(phaseright < 0.5 ? 0.22 - phaseright : phaseright-0.72);
97 bool Wave::insert(
const QVector<qint32> &L,
const QVector<qint32> &R,
98 const bool release,
const double amplitude)
101 qint32 maximalAmplitude = 0;
102 for (
auto &a : L)
if (abs(a)>maximalAmplitude) maximalAmplitude=abs(a);
103 for (
auto &a : R)
if (abs(a)>maximalAmplitude) maximalAmplitude=abs(a);
107 while (maximalAmplitude & 0x7FFF8000) { shift++; maximalAmplitude >>= 1; }
108 int divisor = (1<<shift);
112 if (amplitude > 1) ampshift = round(log(amplitude)/log(2.0));
113 else divisor <<= static_cast<int>(round(-log(amplitude)/log(2.0)));
119 qDebug() <<
"Wave::insert: Wave size" << L.size() <<
"exceeds 2^20";
127 for (
int i=0; i<N; i++)
137 for (
int i=0; i<N; i++)
144 STATUS <<
"Compute envelope and perform automatic cyclic morphing";
163 STATUS <<
"Writing PCM to QIODevice";
165 const int tag=0x11111111;
171 auto writeWaveform = [&iodevice] (QVector<qint16> &wave)
176 QByteArray data = QByteArray::fromRawData(
177 reinterpret_cast<const char*>(wave.constData()),
178 sizeof(qint16) * wave.size());
180 QByteArray compressed = qCompress(data,9);
182 STATUS <<
"Compressing" << 2*wave.size() <<
"->" << compressed.size();
183 int bytes =
static_cast<int>(iodevice.write(compressed));
184 if (bytes != compressed.size())
186 ERROR <<
"Could not write compressed data";
222 auto readWaveform = [&iodevice] (QVector<qint16> &wave)
224 int uncompressedSize=0, compressedSize=0;
226 if (uncompressedSize==0) wave.clear();
230 if (QThread::currentThread()->isInterruptionRequested())
return false;
231 QByteArray array = iodevice.read(compressedSize);
232 QByteArray uncompressed = qUncompress(array);
233 if (uncompressed.size() != 2*uncompressedSize)
235 WARNING <<
"WaveForm::read: incompatible sizes. File corrupted?";
239 wave.resize(uncompressedSize);
240 #if defined(Q_OS_WINRT) 242 for (
int i=0; i<uncompressedSize; i++)
243 { wave[2*i]=uncompressed[i]%256; wave[2*i+1]=uncompressed[i]/256; }
245 memcpy(&wave[0], uncompressed.constData(), uncompressed.size());
247 if (QThread::currentThread()->isInterruptionRequested())
return false;
248 STATUS <<
"Uncompressing" << compressedSize << array.size()
249 <<
"->" << 2*uncompressedSize << uncompressed.size();
277 qDebug() <<
" Key" << keynumber <<
": Waveform containing" 293 const double damping = 0.0007;
296 double slidingPower = 0;
298 for (
int index = 0; index < equilibrationsize; ++index)
quint32 mRepetitionIndex
Index from where on the sample is repeated.
Wave()
Constructor, resetting member variables.
QVector< double > mEnvelope
Amplitude envelope.
QVector< qint16 > mSustainSample
Sound sample when key is pressed.
const int envelopeWidth
Frames per envelope point.
int mReleaseShift
PCM amplitedes shifted # bits to the left.
void printInfo(int keynumber=0)
Debugging function: Write a short summary of the wave data to qDebug()
void automaticCyclicMorphing()
Function defined externally (Importer)
bool insert(const QVector< qint32 > &L, const QVector< qint32 > &R, const bool release, const double amplitude)
void computeEnvelope(int samplerate)
Determine the envelope of the sustain wave.
QVector< qint16 > mReleaseSample
Sound sample when key is releasek.
bool read(QIODevice &iodevice)
Read a wave from disk.
bool write(QIODevice &iodevice)
Write a PCM wave to disk (QIODevice)
static bool read(QIODevice &iodevice, const T &object)
void computeTriangularWave(double frequency, int samplerate, double stereo)
Compute a synthetic triangular wave.
double mRepetitionFactor
Amplitude decrease factor upon repetition.
int mSustainShift
PCM amplitudes shifted # bits to the left.
static bool write(QIODevice &iodevice, const T &object)