Ref T730, code style, adding namespaces

This commit is contained in:
Klaus Basan
2019-09-21 03:29:58 +02:00
committed by Mat Sutcliffe
parent 329b1e8c9a
commit 99edc9cb13
47 changed files with 1136 additions and 801 deletions

View File

@@ -8,8 +8,8 @@
//! \file
#ifndef BLACKSOUND_OPUSDECODER_H
#define BLACKSOUND_OPUSDECODER_H
#ifndef BLACKSOUND_CODECS_OPUSDECODER_H
#define BLACKSOUND_CODECS_OPUSDECODER_H
#include "blacksound/blacksoundexport.h"
#include "opus/opus.h"

View File

@@ -2,33 +2,39 @@
#include <QDebug>
BufferedWaveProvider::BufferedWaveProvider(const QAudioFormat &format, QObject *parent) :
ISampleProvider(parent)
namespace BlackSound
{
// Set buffer size to 10 secs
m_maxBufferSize = format.bytesForDuration(10 * 1000 * 1000);
}
void BufferedWaveProvider::addSamples(const QVector<qint16> &samples)
{
int delta = m_audioBuffer.size() + samples.size() - m_maxBufferSize;
if(delta > 0)
namespace SampleProvider
{
m_audioBuffer.remove(0, delta);
}
m_audioBuffer.append(samples);
}
CBufferedWaveProvider::CBufferedWaveProvider(const QAudioFormat &format, QObject *parent) :
ISampleProvider(parent)
{
// Set buffer size to 10 secs
m_maxBufferSize = format.bytesForDuration(10 * 1000 * 1000);
}
int BufferedWaveProvider::readSamples(QVector<qint16> &samples, qint64 count)
{
qint64 len = qMin(count, static_cast<qint64>(m_audioBuffer.size()));
samples = m_audioBuffer.mid(0, len);
// if (len != 0) qDebug() << "Reading" << count << "samples." << m_audioBuffer.size() << "currently in the buffer.";
m_audioBuffer.remove(0, len);
return len;
}
void CBufferedWaveProvider::addSamples(const QVector<qint16> &samples)
{
int delta = m_audioBuffer.size() + samples.size() - m_maxBufferSize;
if (delta > 0)
{
m_audioBuffer.remove(0, delta);
}
m_audioBuffer.append(samples);
}
void BufferedWaveProvider::clearBuffer()
{
m_audioBuffer.clear();
}
int CBufferedWaveProvider::readSamples(QVector<qint16> &samples, qint64 count)
{
qint64 len = qMin(count, static_cast<qint64>(m_audioBuffer.size()));
samples = m_audioBuffer.mid(0, len);
// if (len != 0) qDebug() << "Reading" << count << "samples." << m_audioBuffer.size() << "currently in the buffer.";
m_audioBuffer.remove(0, len);
return len;
}
void CBufferedWaveProvider::clearBuffer()
{
m_audioBuffer.clear();
}
} // ns
} // ns

View File

@@ -1,3 +1,13 @@
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
//! \file
#ifndef BLACKSOUND_BUFFEREDWAVEPROVIDER_H
#define BLACKSOUND_BUFFEREDWAVEPROVIDER_H
@@ -8,23 +18,31 @@
#include <QByteArray>
#include <QVector>
class BLACKSOUND_EXPORT BufferedWaveProvider : public ISampleProvider
namespace BlackSound
{
Q_OBJECT
namespace SampleProvider
{
//! Buffered wave generator
class BLACKSOUND_EXPORT CBufferedWaveProvider : public ISampleProvider
{
Q_OBJECT
public:
BufferedWaveProvider(const QAudioFormat &format, QObject *parent = nullptr);
public:
//! Ctor
CBufferedWaveProvider(const QAudioFormat &format, QObject *parent = nullptr);
void addSamples(const QVector<qint16> &samples);
virtual int readSamples(QVector<qint16> &samples, qint64 count) override;
void addSamples(const QVector<qint16> &samples);
virtual int readSamples(QVector<qint16> &samples, qint64 count) override;
int getBufferedBytes() const { return m_audioBuffer.size(); }
int getBufferedBytes() const { return m_audioBuffer.size(); }
void clearBuffer();
void clearBuffer();
private:
QVector<qint16> m_audioBuffer;
qint32 m_maxBufferSize;
};
private:
QVector<qint16> m_audioBuffer;
qint32 m_maxBufferSize;
};
}
}
#endif // BUFFEREDWAVEPROVIDER_H
#endif // guard

View File

@@ -1,51 +1,57 @@
#include "equalizersampleprovider.h"
EqualizerSampleProvider::EqualizerSampleProvider(ISampleProvider *sourceProvider, EqualizerPresets preset, QObject *parent) :
ISampleProvider(parent)
namespace BlackSound
{
m_sourceProvider = sourceProvider;
setupPreset(preset);
}
int EqualizerSampleProvider::readSamples(QVector<qint16> &samples, qint64 count)
{
int samplesRead = m_sourceProvider->readSamples(samples, count);
if (m_bypass) return samplesRead;
for (int n = 0; n < samplesRead; n++)
namespace SampleProvider
{
// TODO stereo implementation
for (int band = 0; band < m_filters.size(); band++)
CEqualizerSampleProvider::CEqualizerSampleProvider(ISampleProvider *sourceProvider, EqualizerPresets preset, QObject *parent) :
ISampleProvider(parent)
{
float s = samples[n] / 32768.0f;
s = m_filters[band].process(s);
samples[n] = s * 32768;
m_sourceProvider = sourceProvider;
setupPreset(preset);
}
samples[n] *= m_outputGain;
}
return samplesRead;
}
int CEqualizerSampleProvider::readSamples(QVector<qint16> &samples, qint64 count)
{
int samplesRead = m_sourceProvider->readSamples(samples, count);
if (m_bypass) return samplesRead;
void EqualizerSampleProvider::setupPreset(EqualizerPresets preset)
{
switch (preset)
{
case VHFEmulation:
m_filters.push_back(BiQuadFilter(BiQuadFilterType::HighPass, 44100, 450, 1.0f));
m_filters.push_back(BiQuadFilter(BiQuadFilterType::Peak, 44100, 2200, 0.25, 13.0f));
m_filters.push_back(BiQuadFilter(BiQuadFilterType::LowPass, 44100, 3000, 1.0f));
break;
for (int n = 0; n < samplesRead; n++)
{
// TODO stereo implementation
for (int band = 0; band < m_filters.size(); band++)
{
float s = samples[n] / 32768.0f;
s = m_filters[band].process(s);
samples[n] = s * 32768;
}
samples[n] *= m_outputGain;
}
return samplesRead;
}
void CEqualizerSampleProvider::setupPreset(EqualizerPresets preset)
{
switch (preset)
{
case VHFEmulation:
m_filters.push_back(BiQuadFilter(BiQuadFilterType::HighPass, 44100, 450, 1.0f));
m_filters.push_back(BiQuadFilter(BiQuadFilterType::Peak, 44100, 2200, 0.25, 13.0f));
m_filters.push_back(BiQuadFilter(BiQuadFilterType::LowPass, 44100, 3000, 1.0f));
break;
}
}
double CEqualizerSampleProvider::outputGain() const
{
return m_outputGain;
}
void CEqualizerSampleProvider::setOutputGain(double outputGain)
{
m_outputGain = outputGain;
}
}
}
double EqualizerSampleProvider::outputGain() const
{
return m_outputGain;
}
void EqualizerSampleProvider::setOutputGain(double outputGain)
{
m_outputGain = outputGain;
}

View File

@@ -1,5 +1,15 @@
#ifndef EQUALIZERSAMPLEPROVIDER_H
#define EQUALIZERSAMPLEPROVIDER_H
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
//! \file
#ifndef BLACKSOUND_SAMPLEPROVIDER_EQUALIZERSAMPLEPROVIDER_H
#define BLACKSOUND_SAMPLEPROVIDER_EQUALIZERSAMPLEPROVIDER_H
#include "blacksound/blacksoundexport.h"
#include "blacksound/sampleprovider/sampleprovider.h"
@@ -8,34 +18,41 @@
#include <QSharedPointer>
#include <QVector>
enum EqualizerPresets
namespace BlackSound
{
VHFEmulation = 1
};
namespace SampleProvider
{
//! Equalizer
enum EqualizerPresets
{
VHFEmulation = 1
};
class BLACKSOUND_EXPORT EqualizerSampleProvider : public ISampleProvider
{
Q_OBJECT
class BLACKSOUND_EXPORT CEqualizerSampleProvider : public ISampleProvider
{
Q_OBJECT
public:
EqualizerSampleProvider(ISampleProvider *sourceProvider, EqualizerPresets preset, QObject *parent = nullptr);
public:
CEqualizerSampleProvider(ISampleProvider *sourceProvider, EqualizerPresets preset, QObject *parent = nullptr);
virtual int readSamples(QVector<qint16> &samples, qint64 count) override;
virtual int readSamples(QVector<qint16> &samples, qint64 count) override;
void setBypassEffects(bool value) { m_bypass = value; }
void setBypassEffects(bool value) { m_bypass = value; }
double outputGain() const;
void setOutputGain(double outputGain);
double outputGain() const;
void setOutputGain(double outputGain);
private:
void setupPreset(EqualizerPresets preset);
private:
void setupPreset(EqualizerPresets preset);
ISampleProvider *m_sourceProvider;
ISampleProvider *m_sourceProvider;
int m_channels = 1;
bool m_bypass = false;
double m_outputGain = 1.0;
QVector<BiQuadFilter> m_filters;
};
int m_channels = 1;
bool m_bypass = false;
double m_outputGain = 1.0;
QVector<BiQuadFilter> m_filters;
};
} // ns
} // ns
#endif // EQUALIZERSAMPLEPROVIDER_H
#endif // guard

View File

@@ -1,36 +1,50 @@
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
#include "mixingsampleprovider.h"
int MixingSampleProvider::readSamples(QVector<qint16> &samples, qint64 count)
namespace BlackSound
{
samples.clear();
samples.fill(0, count);
int outputLen = 0;
QVector<ISampleProvider*> finishedProviders;
for (int i = 0; i < m_sources.size(); i++)
namespace SampleProvider
{
ISampleProvider *sampleProvider = m_sources.at(i);
QVector<qint16> sourceBuffer;
int len = sampleProvider->readSamples(sourceBuffer, count);
for (int n = 0; n < len; n++)
int CMixingSampleProvider::readSamples(QVector<qint16> &samples, qint64 count)
{
samples[n] += sourceBuffer[n];
}
samples.clear();
samples.fill(0, count);
int outputLen = 0;
outputLen = qMax(len, outputLen);
QVector<ISampleProvider *> finishedProviders;
for (int i = 0; i < m_sources.size(); i++)
{
ISampleProvider *sampleProvider = m_sources.at(i);
QVector<qint16> sourceBuffer;
int len = sampleProvider->readSamples(sourceBuffer, count);
if (sampleProvider->isFinished())
{
finishedProviders.push_back(sampleProvider);
for (int n = 0; n < len; n++)
{
samples[n] += sourceBuffer[n];
}
outputLen = qMax(len, outputLen);
if (sampleProvider->isFinished())
{
finishedProviders.push_back(sampleProvider);
}
}
for (ISampleProvider *sampleProvider : finishedProviders)
{
sampleProvider->deleteLater();
m_sources.removeAll(sampleProvider);
}
return outputLen;
}
}
for (ISampleProvider *sampleProvider : finishedProviders)
{
sampleProvider->deleteLater();
m_sources.removeAll(sampleProvider);
}
return outputLen;
}

View File

@@ -1,3 +1,13 @@
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
//! \file
#ifndef MIXINGSAMPLEPROVIDER_H
#define MIXINGSAMPLEPROVIDER_H
@@ -6,16 +16,22 @@
#include <QSharedPointer>
#include <QVector>
class BLACKSOUND_EXPORT MixingSampleProvider : public ISampleProvider
namespace BlackSound
{
public:
MixingSampleProvider(QObject * parent = nullptr) : ISampleProvider(parent) {}
namespace SampleProvider
{
class BLACKSOUND_EXPORT CMixingSampleProvider : public ISampleProvider
{
public:
CMixingSampleProvider(QObject *parent = nullptr) : ISampleProvider(parent) {}
void addMixerInput(ISampleProvider *provider) { m_sources.append(provider); }
virtual int readSamples(QVector<qint16> &samples, qint64 count) override;
void addMixerInput(ISampleProvider *provider) { m_sources.append(provider); }
virtual int readSamples(QVector<qint16> &samples, qint64 count) override;
private:
QVector<ISampleProvider*> m_sources;
};
private:
QVector<ISampleProvider *> m_sources;
};
}
}
#endif // MIXINGSAMPLEPROVIDER_H
#endif // guard

View File

@@ -10,25 +10,31 @@
#include "pinknoisegenerator.h"
int PinkNoiseGenerator::readSamples(QVector<qint16> &samples, qint64 count)
namespace BlackSound
{
samples.clear();
samples.fill(0, count);
for (int sampleCount = 0; sampleCount < count; sampleCount++)
namespace SampleProvider
{
double white = 2 * random.generateDouble() - 1;
int CPinkNoiseGenerator::readSamples(QVector<qint16> &samples, qint64 count)
{
samples.clear();
samples.fill(0, count);
pinkNoiseBuffer[0] = 0.99886*pinkNoiseBuffer[0] + white*0.0555179;
pinkNoiseBuffer[1] = 0.99332*pinkNoiseBuffer[1] + white*0.0750759;
pinkNoiseBuffer[2] = 0.96900*pinkNoiseBuffer[2] + white*0.1538520;
pinkNoiseBuffer[3] = 0.86650*pinkNoiseBuffer[3] + white*0.3104856;
pinkNoiseBuffer[4] = 0.55000*pinkNoiseBuffer[4] + white*0.5329522;
pinkNoiseBuffer[5] = -0.7616*pinkNoiseBuffer[5] - white*0.0168980;
double pink = pinkNoiseBuffer[0] + pinkNoiseBuffer[1] + pinkNoiseBuffer[2] + pinkNoiseBuffer[3] + pinkNoiseBuffer[4] + pinkNoiseBuffer[5] + pinkNoiseBuffer[6] + white*0.5362;
pinkNoiseBuffer[6] = white*0.115926;
double sampleValue = (m_gain*(pink/5));
samples[sampleCount] = sampleValue * 32768;
for (int sampleCount = 0; sampleCount < count; sampleCount++)
{
double white = 2 * random.generateDouble() - 1;
pinkNoiseBuffer[0] = 0.99886 * pinkNoiseBuffer[0] + white * 0.0555179;
pinkNoiseBuffer[1] = 0.99332 * pinkNoiseBuffer[1] + white * 0.0750759;
pinkNoiseBuffer[2] = 0.96900 * pinkNoiseBuffer[2] + white * 0.1538520;
pinkNoiseBuffer[3] = 0.86650 * pinkNoiseBuffer[3] + white * 0.3104856;
pinkNoiseBuffer[4] = 0.55000 * pinkNoiseBuffer[4] + white * 0.5329522;
pinkNoiseBuffer[5] = -0.7616 * pinkNoiseBuffer[5] - white * 0.0168980;
double pink = pinkNoiseBuffer[0] + pinkNoiseBuffer[1] + pinkNoiseBuffer[2] + pinkNoiseBuffer[3] + pinkNoiseBuffer[4] + pinkNoiseBuffer[5] + pinkNoiseBuffer[6] + white * 0.5362;
pinkNoiseBuffer[6] = white * 0.115926;
double sampleValue = (m_gain * (pink / 5));
samples[sampleCount] = sampleValue * 32768;
}
return count;
}
}
return count;
}

View File

@@ -19,23 +19,29 @@
#include <array>
//! Pink noise generator
class BLACKSOUND_EXPORT PinkNoiseGenerator : public ISampleProvider
namespace BlackSound
{
Q_OBJECT
namespace SampleProvider
{
//! Pink noise generator
class BLACKSOUND_EXPORT CPinkNoiseGenerator : public ISampleProvider
{
Q_OBJECT
public:
//! Noise generator
PinkNoiseGenerator(QObject *parent = nullptr) : ISampleProvider(parent) {}
public:
//! Noise generator
CPinkNoiseGenerator(QObject *parent = nullptr) : ISampleProvider(parent) {}
virtual int readSamples(QVector<qint16> &samples, qint64 count) override;
virtual int readSamples(QVector<qint16> &samples, qint64 count) override;
void setGain(double gain) { m_gain = gain; }
void setGain(double gain) { m_gain = gain; }
private:
QRandomGenerator random;
std::array<double, 7> pinkNoiseBuffer = {0};
double m_gain = 0.0;
};
private:
QRandomGenerator random;
std::array<double, 7> pinkNoiseBuffer = {0};
double m_gain = 0.0;
};
}
}
#endif // guard

View File

@@ -1,22 +1,39 @@
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
//! \file
#include "resourcesound.h"
#include "audioutilities.h"
ResourceSound::ResourceSound(const QString &audioFileName)
{
m_wavFile = new WavFile;
m_wavFile->open(audioFileName);
if (m_wavFile->fileFormat().sampleType() == QAudioFormat::Float)
{
m_samples = convertFloatBytesTo16BitPCM(m_wavFile->audioData());
}
else
{
m_samples = convertBytesTo16BitPCM(m_wavFile->audioData());
}
using namespace BlackSound::Wav;
}
const QVector<qint16>& ResourceSound::audioData()
namespace BlackSound
{
return m_samples;
namespace SampleProvider
{
CResourceSound::CResourceSound(const QString &audioFileName)
{
m_wavFile = new WavFile;
m_wavFile->open(audioFileName);
if (m_wavFile->fileFormat().sampleType() == QAudioFormat::Float)
{
m_samples = convertFloatBytesTo16BitPCM(m_wavFile->audioData());
}
else
{
m_samples = convertBytesTo16BitPCM(m_wavFile->audioData());
}
}
const QVector<qint16> &CResourceSound::audioData()
{
return m_samples;
}
}
}

View File

@@ -1,5 +1,15 @@
#ifndef RESOURCESOUND_H
#define RESOURCESOUND_H
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
//! \file
#ifndef BLACKSOUND_SAMPLEPROVIDER_RESOURCESOUND_H
#define BLACKSOUND_SAMPLEPROVIDER_RESOURCESOUND_H
#include "blacksound/blacksoundexport.h"
#include "blacksound/wav/wavfile.h"
@@ -7,16 +17,24 @@
#include <QString>
#include <QVector>
class ResourceSound
namespace BlackSound
{
public:
ResourceSound(const QString &audioFileName);
namespace SampleProvider
{
//! File from resources
class CResourceSound
{
public:
//! Sound of audio file
CResourceSound(const QString &audioFileName);
const QVector<qint16> &audioData();
const QVector<qint16> &audioData();
private:
WavFile *m_wavFile;
QVector<qint16> m_samples;
};
private:
Wav::WavFile *m_wavFile = nullptr;
QVector<qint16> m_samples;
};
}
}
#endif // RESOURCESOUND_H
#endif // guard

View File

@@ -1,76 +1,82 @@
#include "resourcesoundsampleprovider.h"
#include <QDebug>
ResourceSoundSampleProvider::ResourceSoundSampleProvider(const ResourceSound &resourceSound, QObject *parent) :
ISampleProvider(parent),
m_resourceSound(resourceSound)
namespace BlackSound
{
tempBuffer.resize(tempBufferSize);
}
int ResourceSoundSampleProvider::readSamples(QVector<qint16> &samples, qint64 count)
{
if (count > tempBufferSize)
namespace SampleProvider
{
qDebug() << "Count too large for temp buffer";
return 0;
}
qint64 availableSamples = m_resourceSound.audioData().size() - position;
qint64 samplesToCopy = qMin(availableSamples, count);
samples.clear();
samples.fill(0, samplesToCopy);
for (qint64 i = 0; i < samplesToCopy; i++)
{
tempBuffer[i] = m_resourceSound.audioData().at(position + i);
}
if (m_gain != 1.0f)
{
for (int i = 0; i < samplesToCopy; i++)
CResourceSoundSampleProvider::CResourceSoundSampleProvider(const CResourceSound &resourceSound, QObject *parent) :
ISampleProvider(parent),
m_resourceSound(resourceSound)
{
tempBuffer[i] *= m_gain;
tempBuffer.resize(tempBufferSize);
}
int CResourceSoundSampleProvider::readSamples(QVector<qint16> &samples, qint64 count)
{
if (count > tempBufferSize)
{
qDebug() << "Count too large for temp buffer";
return 0;
}
qint64 availableSamples = m_resourceSound.audioData().size() - position;
qint64 samplesToCopy = qMin(availableSamples, count);
samples.clear();
samples.fill(0, samplesToCopy);
for (qint64 i = 0; i < samplesToCopy; i++)
{
tempBuffer[i] = m_resourceSound.audioData().at(position + i);
}
if (m_gain != 1.0f)
{
for (int i = 0; i < samplesToCopy; i++)
{
tempBuffer[i] *= m_gain;
}
}
for (qint64 i = 0; i < samplesToCopy; i++)
{
samples[i] = tempBuffer.at(i);
}
position += samplesToCopy;
if (position > availableSamples - 1)
{
if (m_looping) { position = 0; }
else { m_isFinished = true; }
}
return (int)samplesToCopy;
}
bool CResourceSoundSampleProvider::isFinished()
{
return m_isFinished;
}
bool CResourceSoundSampleProvider::looping() const
{
return m_looping;
}
void CResourceSoundSampleProvider::setLooping(bool looping)
{
m_looping = looping;
}
float CResourceSoundSampleProvider::gain() const
{
return m_gain;
}
void CResourceSoundSampleProvider::setGain(float gain)
{
m_gain = gain;
}
}
for (qint64 i = 0; i < samplesToCopy; i++)
{
samples[i] = tempBuffer.at(i);
}
position += samplesToCopy;
if (position > availableSamples - 1)
{
if (m_looping) { position = 0; }
else { m_isFinished = true; }
}
return (int)samplesToCopy;
}
bool ResourceSoundSampleProvider::isFinished()
{
return m_isFinished;
}
bool ResourceSoundSampleProvider::looping() const
{
return m_looping;
}
void ResourceSoundSampleProvider::setLooping(bool looping)
{
m_looping = looping;
}
float ResourceSoundSampleProvider::gain() const
{
return m_gain;
}
void ResourceSoundSampleProvider::setGain(float gain)
{
m_gain = gain;
}

View File

@@ -1,37 +1,51 @@
#ifndef RESOURCESOUNDSAMPLEPROVIDER_H
#define RESOURCESOUNDSAMPLEPROVIDER_H
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
#ifndef BLACKSOUND_SAMPLEPROVIDER_RESOURCESOUNDSAMPLEPROVIDER_H
#define BLACKSOUND_SAMPLEPROVIDER_RESOURCESOUNDSAMPLEPROVIDER_H
#include "blacksound/blacksoundexport.h"
#include "sampleprovider.h"
#include "resourcesound.h"
//! A sample provider
class BLACKSOUND_EXPORT ResourceSoundSampleProvider : public ISampleProvider
namespace BlackSound
{
Q_OBJECT
namespace SampleProvider
{
//! A sample provider
class BLACKSOUND_EXPORT CResourceSoundSampleProvider : public ISampleProvider
{
Q_OBJECT
public:
//! Ctor
ResourceSoundSampleProvider(const ResourceSound &resourceSound, QObject *parent = nullptr);
public:
//! Ctor
CResourceSoundSampleProvider(const CResourceSound &resourceSound, QObject *parent = nullptr);
virtual int readSamples(QVector<qint16> &samples, qint64 count) override;
virtual bool isFinished() override;
virtual int readSamples(QVector<qint16> &samples, qint64 count) override;
virtual bool isFinished() override;
bool looping() const;
void setLooping(bool looping);
bool looping() const;
void setLooping(bool looping);
float gain() const;
void setGain(float gain);
float gain() const;
void setGain(float gain);
private:
float m_gain = 1.0f;
bool m_looping = false;
private:
float m_gain = 1.0f;
bool m_looping = false;
ResourceSound m_resourceSound;
qint64 position = 0;
const int tempBufferSize = 9600; //9600 = 200ms
QVector<qint16> tempBuffer;
bool m_isFinished = false;
};
CResourceSound m_resourceSound;
qint64 position = 0;
const int tempBufferSize = 9600; //9600 = 200ms
QVector<qint16> tempBuffer;
bool m_isFinished = false;
};
}
}
#endif // RESOURCESOUNDSAMPLEPROVIDER_H
#endif // guard

View File

@@ -1,3 +1,13 @@
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
//! \file
#ifndef SAMPLEPROVIDER_H
#define SAMPLEPROVIDER_H
@@ -5,17 +15,24 @@
#include <QObject>
#include <QVector>
class BLACKSOUND_EXPORT ISampleProvider : public QObject
namespace BlackSound
{
Q_OBJECT
namespace SampleProvider
{
//! Sample provider interface
class BLACKSOUND_EXPORT ISampleProvider : public QObject
{
Q_OBJECT
public:
ISampleProvider(QObject *parent = nullptr) : QObject(parent) {}
virtual ~ISampleProvider() {}
public:
ISampleProvider(QObject *parent = nullptr) : QObject(parent) {}
virtual ~ISampleProvider() override {}
virtual int readSamples(QVector<qint16> &samples, qint64 count) = 0;
virtual int readSamples(QVector<qint16> &samples, qint64 count) = 0;
virtual bool isFinished() { return false; }
};
virtual bool isFinished() { return false; }
};
}
}
#endif // SAMPLEPROVIDER_H
#endif // guard

View File

@@ -1,29 +1,43 @@
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
#include "samples.h"
#include "blackmisc/directoryutils.h"
Samples &Samples::instance()
namespace BlackSound
{
static Samples samples;
return samples;
}
namespace SampleProvider
{
Samples &Samples::instance()
{
static Samples samples;
return samples;
}
Samples::Samples() :
m_crackle(BlackMisc::CDirectoryUtils::soundFilesDirectory() + "/Crackle_f32.wav"),
m_click(BlackMisc::CDirectoryUtils::soundFilesDirectory() + "/Click_f32.wav"),
m_whiteNoise(BlackMisc::CDirectoryUtils::soundFilesDirectory() + "/WhiteNoise_f32.wav")
{ }
Samples::Samples() :
m_crackle(BlackMisc::CDirectoryUtils::soundFilesDirectory() + "/Crackle_f32.wav"),
m_click(BlackMisc::CDirectoryUtils::soundFilesDirectory() + "/Click_f32.wav"),
m_whiteNoise(BlackMisc::CDirectoryUtils::soundFilesDirectory() + "/WhiteNoise_f32.wav")
{ }
ResourceSound Samples::click() const
{
return m_click;
}
CResourceSound Samples::click() const
{
return m_click;
}
ResourceSound Samples::crackle() const
{
return m_crackle;
}
CResourceSound Samples::crackle() const
{
return m_crackle;
}
ResourceSound Samples::whiteNoise() const
{
return m_whiteNoise;
CResourceSound Samples::whiteNoise() const
{
return m_whiteNoise;
}
}
}

View File

@@ -1,24 +1,40 @@
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
//! \file
#ifndef SAMPLES_H
#define SAMPLES_H
#include "blacksound/blacksoundexport.h"
#include "resourcesound.h"
class BLACKSOUND_EXPORT Samples
namespace BlackSound
{
public:
static Samples &instance();
namespace SampleProvider
{
class BLACKSOUND_EXPORT Samples
{
public:
static Samples &instance();
ResourceSound crackle() const;
ResourceSound click() const;
ResourceSound whiteNoise() const;
CResourceSound crackle() const;
CResourceSound click() const;
CResourceSound whiteNoise() const;
private:
Samples();
private:
Samples();
ResourceSound m_crackle;
ResourceSound m_click;
ResourceSound m_whiteNoise;
};
CResourceSound m_crackle;
CResourceSound m_click;
CResourceSound m_whiteNoise;
};
}
}
#endif // SAMPLES_H

View File

@@ -1,23 +1,37 @@
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
#include "sawtoothgenerator.h"
#include <cmath>
SawToothGenerator::SawToothGenerator(double frequency, QObject *parent) :
ISampleProvider(parent),
m_frequency(frequency)
{}
int SawToothGenerator::readSamples(QVector<qint16> &samples, qint64 count)
namespace BlackSound
{
samples.clear();
samples.fill(0, count);
for (int sampleCount = 0; sampleCount < count; sampleCount++)
namespace SampleProvider
{
double multiple = 2 * m_frequency / m_sampleRate;
double sampleSaw = std::fmod((m_nSample * multiple), 2) - 1;
double sampleValue = m_gain * sampleSaw;
samples[sampleCount] = sampleValue * 32768;
m_nSample++;
CSawToothGenerator::CSawToothGenerator(double frequency, QObject *parent) :
ISampleProvider(parent),
m_frequency(frequency)
{}
int CSawToothGenerator::readSamples(QVector<qint16> &samples, qint64 count)
{
samples.clear();
samples.fill(0, count);
for (int sampleCount = 0; sampleCount < count; sampleCount++)
{
double multiple = 2 * m_frequency / m_sampleRate;
double sampleSaw = std::fmod((m_nSample * multiple), 2) - 1;
double sampleValue = m_gain * sampleSaw;
samples[sampleCount] = sampleValue * 32768;
m_nSample++;
}
return static_cast<int>(count);
}
}
return count;
}

View File

@@ -1,30 +1,45 @@
#ifndef SAWTOOTHGENERATOR_H
#define SAWTOOTHGENERATOR_H
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
//! \file
#ifndef BLACKSOUND_SAMPLEPROVIDER_SAWTOOTHGENERATOR_H
#define BLACKSOUND_SAMPLEPROVIDER_SAWTOOTHGENERATOR_H
#include "blacksound/blacksoundexport.h"
#include "blacksound/sampleprovider/sampleprovider.h"
#include <QRandomGenerator>
#include <QVector>
#include <array>
class BLACKSOUND_EXPORT SawToothGenerator : public ISampleProvider
namespace BlackSound
{
Q_OBJECT
namespace SampleProvider
{
//! Saw tooth generator
class BLACKSOUND_EXPORT CSawToothGenerator : public ISampleProvider
{
Q_OBJECT
public:
SawToothGenerator(double frequency, QObject *parent = nullptr);
public:
CSawToothGenerator(double frequency, QObject *parent = nullptr);
virtual int readSamples(QVector<qint16> &samples, qint64 count) override;
virtual int readSamples(QVector<qint16> &samples, qint64 count) override;
void setGain(double gain) { m_gain = gain; }
void setGain(double gain) { m_gain = gain; }
private:
double m_gain = 0.0;
double m_frequency = 0.0;
double m_sampleRate = 48000;
int m_nSample = 0;
};
private:
double m_gain = 0.0;
double m_frequency = 0.0;
double m_sampleRate = 48000;
int m_nSample = 0;
};
}
}
#endif // SAWTOOTHGENERATOR_H
#endif // guard

View File

@@ -1,45 +1,59 @@
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
#include "simplecompressoreffect.h"
#include <QDebug>
SimpleCompressorEffect::SimpleCompressorEffect(ISampleProvider *source, QObject *parent) :
ISampleProvider(parent),
m_sourceStream(source)
namespace BlackSound
{
m_simpleCompressor.setAttack(5.0);
m_simpleCompressor.setRelease(10.0);
m_simpleCompressor.setSampleRate(48000.0);
m_simpleCompressor.setThresh(16.0);
m_simpleCompressor.setRatio(6.0);
m_simpleCompressor.setMakeUpGain(16.0);
m_timer.start(3000);
}
int SimpleCompressorEffect::readSamples(QVector<qint16> &samples, qint64 count)
{
int samplesRead = m_sourceStream->readSamples(samples, count);
if (m_enabled)
namespace SampleProvider
{
for (int sample = 0; sample < samplesRead; sample+=channels)
CSimpleCompressorEffect::CSimpleCompressorEffect(ISampleProvider *source, QObject *parent) :
ISampleProvider(parent),
m_sourceStream(source)
{
double in1 = samples.at(sample) / 32768.0;
double in2 = (channels == 1) ? 0 : samples.at(sample+1);
m_simpleCompressor.process(in1, in2);
samples[sample] = in1 * 32768.0;
if (channels > 1)
samples[sample + 1] = in2 * 32768.0f;
m_simpleCompressor.setAttack(5.0);
m_simpleCompressor.setRelease(10.0);
m_simpleCompressor.setSampleRate(48000.0);
m_simpleCompressor.setThresh(16.0);
m_simpleCompressor.setRatio(6.0);
m_simpleCompressor.setMakeUpGain(16.0);
m_timer.start(3000);
}
int CSimpleCompressorEffect::readSamples(QVector<qint16> &samples, qint64 count)
{
int samplesRead = m_sourceStream->readSamples(samples, count);
if (m_enabled)
{
for (int sample = 0; sample < samplesRead; sample += channels)
{
double in1 = samples.at(sample) / 32768.0;
double in2 = (channels == 1) ? 0 : samples.at(sample + 1);
m_simpleCompressor.process(in1, in2);
samples[sample] = in1 * 32768.0;
if (channels > 1)
samples[sample + 1] = in2 * 32768.0f;
}
}
return samplesRead;
}
void CSimpleCompressorEffect::setEnabled(bool enabled)
{
m_enabled = enabled;
}
void CSimpleCompressorEffect::setMakeUpGain(double gain)
{
m_simpleCompressor.setMakeUpGain(gain);
}
}
return samplesRead;
}
void SimpleCompressorEffect::setEnabled(bool enabled)
{
m_enabled = enabled;
}
void SimpleCompressorEffect::setMakeUpGain(double gain)
{
m_simpleCompressor.setMakeUpGain(gain);
}

View File

@@ -1,5 +1,15 @@
#ifndef SIMPLECOMPRESSOREFFECT_H
#define SIMPLECOMPRESSOREFFECT_H
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
//! \file
#ifndef BLACKSOUND_SAMPLEPROVIDER_SIMPLECOMPRESSOREFFECT_H
#define BLACKSOUND_SAMPLEPROVIDER_SIMPLECOMPRESSOREFFECT_H
#include "blacksound/blacksoundexport.h"
#include "sampleprovider.h"
@@ -8,25 +18,31 @@
#include <QObject>
#include <QTimer>
class BLACKSOUND_EXPORT SimpleCompressorEffect : public ISampleProvider
namespace BlackSound
{
Q_OBJECT
namespace SampleProvider
{
class BLACKSOUND_EXPORT CSimpleCompressorEffect : public ISampleProvider
{
Q_OBJECT
public:
SimpleCompressorEffect(ISampleProvider *source, QObject *parent = nullptr);
public:
CSimpleCompressorEffect(ISampleProvider *source, QObject *parent = nullptr);
virtual int readSamples(QVector<qint16> &samples, qint64 count) override;
virtual int readSamples(QVector<qint16> &samples, qint64 count) override;
void setEnabled(bool enabled);
void setMakeUpGain(double gain);
void setEnabled(bool enabled);
void setMakeUpGain(double gain);
private:
private:
QTimer m_timer;
ISampleProvider *m_sourceStream;
bool m_enabled = true;
chunkware_simple::SimpleComp m_simpleCompressor;
const int channels = 1;
};
QTimer m_timer;
ISampleProvider *m_sourceStream;
bool m_enabled = true;
chunkware_simple::SimpleComp m_simpleCompressor;
const int channels = 1;
};
}
}
#endif // SIMPLECOMPRESSOREFFECT_H
#endif // guard

View File

@@ -8,33 +8,30 @@
//! \file
#include "volumesampleprovider.h"
#include "volumesampleprovider.h"
VolumeSampleProvider::VolumeSampleProvider(ISampleProvider *sourceProvider, QObject *parent) :
ISampleProvider(parent),
m_sourceProvider(sourceProvider)
{ }
int VolumeSampleProvider::readSamples(QVector<qint16> &samples, qint64 count)
namespace BlackSound
{
int samplesRead = m_sourceProvider->readSamples(samples, count);
if (! qFuzzyCompare(m_volume, 1.0))
namespace SampleProvider
{
for (int n = 0; n < samplesRead; n++)
CVolumeSampleProvider::CVolumeSampleProvider(ISampleProvider *sourceProvider, QObject *parent) :
ISampleProvider(parent),
m_sourceProvider(sourceProvider)
{ }
int CVolumeSampleProvider::readSamples(QVector<qint16> &samples, qint64 count)
{
samples[n] *= m_volume;
int samplesRead = m_sourceProvider->readSamples(samples, count);
if (! qFuzzyCompare(m_volume, 1.0))
{
for (int n = 0; n < samplesRead; n++)
{
samples[n] *= m_volume;
}
}
return samplesRead;
}
}
return samplesRead;
}
double VolumeSampleProvider::volume() const
{
return m_volume;
}
void VolumeSampleProvider::setVolume(double volume)
{
m_volume = volume;
}

View File

@@ -8,29 +8,35 @@
//! \file
#ifndef VOLUMESAMPLEPROVIDER_H
#define VOLUMESAMPLEPROVIDER_H
#ifndef BLACKSOUND_SAMPLEPROVIDER_VOLUMESAMPLEPROVIDER_H
#define BLACKSOUND_SAMPLEPROVIDER_VOLUMESAMPLEPROVIDER_H
#include "blacksound/blacksoundexport.h"
#include "blacksound/sampleprovider/sampleprovider.h"
//! Pink noise generator
class BLACKSOUND_EXPORT VolumeSampleProvider : public ISampleProvider
namespace BlackSound
{
Q_OBJECT
namespace SampleProvider
{
//! Pink noise generator
class BLACKSOUND_EXPORT CVolumeSampleProvider : public ISampleProvider
{
Q_OBJECT
public:
//! Noise generator
VolumeSampleProvider(ISampleProvider *sourceProvider, QObject *parent = nullptr);
public:
//! Noise generator
CVolumeSampleProvider(ISampleProvider *sourceProvider, QObject *parent = nullptr);
virtual int readSamples(QVector<qint16> &samples, qint64 count) override;
virtual int readSamples(QVector<qint16> &samples, qint64 count) override;
double volume() const;
void setVolume(double volume);
double volume() const { return m_volume; }
void setVolume(double volume) { m_volume = volume; }
private:
ISampleProvider *m_sourceProvider;
double m_volume = 1.0;
};
private:
ISampleProvider *m_sourceProvider = nullptr;
double m_volume = 1.0;
};
}
}
#endif // guard

View File

@@ -1,133 +1,147 @@
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
#include <qendian.h>
#include <QVector>
#include <QDebug>
// #include "utils.h"
#include "wavfile.h"
struct chunk
namespace BlackSound
{
char id[4];
quint32 size;
};
struct RIFFHeader
{
chunk descriptor; // "RIFF"
char type[4]; // "WAVE"
};
struct WAVEHeader
{
chunk descriptor;
quint16 audioFormat;
quint16 numChannels;
quint32 sampleRate;
quint32 byteRate;
quint16 blockAlign;
quint16 bitsPerSample;
};
struct DATAHeader
{
chunk descriptor;
};
struct CombinedHeader
{
RIFFHeader riff;
WAVEHeader wave;
};
WavFile::WavFile(QObject *parent) :
QFile(parent),
m_headerLength(0)
{ }
bool WavFile::open(const QString &fileName)
{
close();
setFileName(fileName);
return QFile::open(QIODevice::ReadOnly) && readHeader();
}
const QAudioFormat &WavFile::fileFormat() const
{
return m_fileFormat;
}
qint64 WavFile::headerLength() const
{
return m_headerLength;
}
bool WavFile::readHeader()
{
seek(0);
CombinedHeader header;
DATAHeader dataHeader;
bool result = read(reinterpret_cast<char *>(&header), sizeof(CombinedHeader)) == sizeof(CombinedHeader);
if (result)
namespace Wav
{
if ((memcmp(&header.riff.descriptor.id, "RIFF", 4) == 0
|| memcmp(&header.riff.descriptor.id, "RIFX", 4) == 0)
&& memcmp(&header.riff.type, "WAVE", 4) == 0
&& memcmp(&header.wave.descriptor.id, "fmt ", 4) == 0
&& (header.wave.audioFormat == 1 || header.wave.audioFormat == 0 || header.wave.audioFormat == 3))
struct chunk
{
// Read off remaining header information
if (qFromLittleEndian<quint32>(header.wave.descriptor.size) > sizeof(WAVEHeader))
char id[4];
quint32 size;
};
struct RIFFHeader
{
chunk descriptor; // "RIFF"
char type[4]; // "WAVE"
};
struct WAVEHeader
{
chunk descriptor;
quint16 audioFormat;
quint16 numChannels;
quint32 sampleRate;
quint32 byteRate;
quint16 blockAlign;
quint16 bitsPerSample;
};
struct DATAHeader
{
chunk descriptor;
};
struct CombinedHeader
{
RIFFHeader riff;
WAVEHeader wave;
};
WavFile::WavFile(QObject *parent) :
QFile(parent),
m_headerLength(0)
{ }
bool WavFile::open(const QString &fileName)
{
close();
setFileName(fileName);
return QFile::open(QIODevice::ReadOnly) && readHeader();
}
const QAudioFormat &WavFile::fileFormat() const
{
return m_fileFormat;
}
qint64 WavFile::headerLength() const
{
return m_headerLength;
}
bool WavFile::readHeader()
{
seek(0);
CombinedHeader header;
DATAHeader dataHeader;
bool result = read(reinterpret_cast<char *>(&header), sizeof(CombinedHeader)) == sizeof(CombinedHeader);
if (result)
{
// Extended data available
quint16 extraFormatBytes;
if (peek((char*)&extraFormatBytes, sizeof(quint16)) != sizeof(quint16))
return false;
const qint64 throwAwayBytes = sizeof(quint16) + qFromLittleEndian<quint16>(extraFormatBytes);
if (read(throwAwayBytes).size() != throwAwayBytes)
if ((memcmp(&header.riff.descriptor.id, "RIFF", 4) == 0
|| memcmp(&header.riff.descriptor.id, "RIFX", 4) == 0)
&& memcmp(&header.riff.type, "WAVE", 4) == 0
&& memcmp(&header.wave.descriptor.id, "fmt ", 4) == 0
&& (header.wave.audioFormat == 1 || header.wave.audioFormat == 0 || header.wave.audioFormat == 3))
{
// Read off remaining header information
if (qFromLittleEndian<quint32>(header.wave.descriptor.size) > sizeof(WAVEHeader))
{
// Extended data available
quint16 extraFormatBytes;
if (peek((char *)&extraFormatBytes, sizeof(quint16)) != sizeof(quint16))
return false;
const qint64 throwAwayBytes = sizeof(quint16) + qFromLittleEndian<quint16>(extraFormatBytes);
if (read(throwAwayBytes).size() != throwAwayBytes)
return false;
}
if (read((char *)&dataHeader, sizeof(DATAHeader)) != sizeof(DATAHeader))
return false;
// Establish format
if (memcmp(&header.riff.descriptor.id, "RIFF", 4) == 0)
m_fileFormat.setByteOrder(QAudioFormat::LittleEndian);
else
m_fileFormat.setByteOrder(QAudioFormat::BigEndian);
int bps = qFromLittleEndian<quint16>(header.wave.bitsPerSample);
m_fileFormat.setChannelCount(qFromLittleEndian<quint16>(header.wave.numChannels));
m_fileFormat.setCodec("audio/pcm");
m_fileFormat.setSampleRate(qFromLittleEndian<quint32>(header.wave.sampleRate));
m_fileFormat.setSampleSize(qFromLittleEndian<quint16>(header.wave.bitsPerSample));
if (header.wave.audioFormat == 1 || header.wave.audioFormat == 0)
{
m_fileFormat.setSampleType(bps == 8 ? QAudioFormat::UnSignedInt : QAudioFormat::SignedInt);
}
else
{
m_fileFormat.setSampleType(QAudioFormat::Float);
}
}
else
{
result = false;
}
}
m_headerLength = pos();
if (memcmp(&dataHeader.descriptor.id, "data", 4) == 0)
{
qint32 dataLength = qFromLittleEndian<qint32>(dataHeader.descriptor.size);
m_audioData = read(dataLength);
if (m_audioData.size() != dataLength)
{
return false;
m_audioData.clear();
}
}
if (read((char*)&dataHeader, sizeof(DATAHeader)) != sizeof(DATAHeader))
return false;
// Establish format
if (memcmp(&header.riff.descriptor.id, "RIFF", 4) == 0)
m_fileFormat.setByteOrder(QAudioFormat::LittleEndian);
else
m_fileFormat.setByteOrder(QAudioFormat::BigEndian);
int bps = qFromLittleEndian<quint16>(header.wave.bitsPerSample);
m_fileFormat.setChannelCount(qFromLittleEndian<quint16>(header.wave.numChannels));
m_fileFormat.setCodec("audio/pcm");
m_fileFormat.setSampleRate(qFromLittleEndian<quint32>(header.wave.sampleRate));
m_fileFormat.setSampleSize(qFromLittleEndian<quint16>(header.wave.bitsPerSample));
if (header.wave.audioFormat == 1 || header.wave.audioFormat == 0)
{
m_fileFormat.setSampleType(bps == 8 ? QAudioFormat::UnSignedInt : QAudioFormat::SignedInt);
}
else
{
m_fileFormat.setSampleType(QAudioFormat::Float);
}
return result;
}
else
{
result = false;
}
}
m_headerLength = pos();
if (memcmp(&dataHeader.descriptor.id, "data", 4) == 0)
{
qint32 dataLength = qFromLittleEndian<qint32>(dataHeader.descriptor.size);
m_audioData = read(dataLength);
if (m_audioData.size() != dataLength)
{
return false;
m_audioData.clear();
}
}
return result;
}
} // ns
} // ns

View File

@@ -1,3 +1,13 @@
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
//! \file
#ifndef WAVFILE_H
#define WAVFILE_H
@@ -5,24 +15,32 @@
#include <QFile>
#include <QAudioFormat>
class WavFile : public QFile
namespace BlackSound
{
public:
WavFile(QObject *parent = 0);
namespace Wav
{
//! * WAV file
class WavFile : public QFile
{
public:
//! Ctor
WavFile(QObject *parent = nullptr);
using QFile::open;
bool open(const QString &fileName);
const QAudioFormat &fileFormat() const;
qint64 headerLength() const;
QByteArray audioData() { return m_audioData; }
using QFile::open;
bool open(const QString &fileName);
const QAudioFormat &fileFormat() const;
qint64 headerLength() const;
QByteArray audioData() { return m_audioData; }
private:
bool readHeader();
private:
bool readHeader();
private:
QAudioFormat m_fileFormat;
qint64 m_headerLength;
QByteArray m_audioData;
};
private:
QAudioFormat m_fileFormat;
qint64 m_headerLength;
QByteArray m_audioData;
};
} // ns
} // ns
#endif // WAVFILE_H
#endif // guard