centralize and fixup example sources install targets
This follows suit with aeb036e in qtbase. Change-Id: Ie8580d0a1f38ab9858b0e44c9f99bdc552a1752a Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com> Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
committed by
The Qt Project
parent
90c8ba233b
commit
6b4994c265
188
examples/multimedia/audiodecoder/audiodecoder.cpp
Normal file
188
examples/multimedia/audiodecoder/audiodecoder.cpp
Normal file
@@ -0,0 +1,188 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "audiodecoder.h"
|
||||
#include <stdio.h>
|
||||
|
||||
AudioDecoder::AudioDecoder(bool isPlayback, bool isDelete)
|
||||
: m_cout(stdout, QIODevice::WriteOnly)
|
||||
{
|
||||
m_isPlayback = isPlayback;
|
||||
m_isDelete = isDelete;
|
||||
|
||||
// Make sure the data we receive is in correct PCM format.
|
||||
// Our wav file writer only supports SignedInt sample type.
|
||||
QAudioFormat format;
|
||||
format.setChannelCount(2);
|
||||
format.setSampleSize(16);
|
||||
format.setSampleRate(48000);
|
||||
format.setCodec("audio/pcm");
|
||||
format.setSampleType(QAudioFormat::SignedInt);
|
||||
m_decoder.setAudioFormat(format);
|
||||
|
||||
connect(&m_decoder, SIGNAL(bufferReady()), this, SLOT(bufferReady()));
|
||||
connect(&m_decoder, SIGNAL(error(QAudioDecoder::Error)), this, SLOT(error(QAudioDecoder::Error)));
|
||||
connect(&m_decoder, SIGNAL(stateChanged(QAudioDecoder::State)), this, SLOT(stateChanged(QAudioDecoder::State)));
|
||||
connect(&m_decoder, SIGNAL(finished()), this, SLOT(finished()));
|
||||
connect(&m_decoder, SIGNAL(positionChanged(qint64)), this, SLOT(updateProgress()));
|
||||
connect(&m_decoder, SIGNAL(durationChanged(qint64)), this, SLOT(updateProgress()));
|
||||
|
||||
connect(&m_soundEffect, SIGNAL(statusChanged()), this, SLOT(playbackStatusChanged()));
|
||||
connect(&m_soundEffect, SIGNAL(playingChanged()), this, SLOT(playingChanged()));
|
||||
|
||||
m_progress = -1.0;
|
||||
}
|
||||
|
||||
void AudioDecoder::setSourceFilename(const QString &fileName)
|
||||
{
|
||||
m_decoder.setSourceFilename(fileName);
|
||||
}
|
||||
|
||||
void AudioDecoder::start()
|
||||
{
|
||||
m_decoder.start();
|
||||
}
|
||||
|
||||
void AudioDecoder::stop()
|
||||
{
|
||||
m_decoder.stop();
|
||||
}
|
||||
|
||||
void AudioDecoder::setTargetFilename(const QString &fileName)
|
||||
{
|
||||
m_targetFilename = fileName;
|
||||
}
|
||||
|
||||
void AudioDecoder::bufferReady()
|
||||
{
|
||||
// read a buffer from audio decoder
|
||||
QAudioBuffer buffer = m_decoder.read();
|
||||
if (!buffer.isValid())
|
||||
return;
|
||||
|
||||
if (!m_fileWriter.isOpen() && !m_fileWriter.open(m_targetFilename, buffer.format())) {
|
||||
m_decoder.stop();
|
||||
return;
|
||||
}
|
||||
|
||||
m_fileWriter.write(buffer);
|
||||
}
|
||||
|
||||
void AudioDecoder::error(QAudioDecoder::Error error)
|
||||
{
|
||||
switch (error) {
|
||||
case QAudioDecoder::NoError:
|
||||
return;
|
||||
case QAudioDecoder::ResourceError:
|
||||
m_cout << "Resource error" << endl;
|
||||
break;
|
||||
case QAudioDecoder::FormatError:
|
||||
m_cout << "Format error" << endl;
|
||||
break;
|
||||
case QAudioDecoder::AccessDeniedError:
|
||||
m_cout << "Access denied error" << endl;
|
||||
break;
|
||||
case QAudioDecoder::ServiceMissingError:
|
||||
m_cout << "Service missing error" << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
emit done();
|
||||
}
|
||||
|
||||
void AudioDecoder::stateChanged(QAudioDecoder::State newState)
|
||||
{
|
||||
switch (newState) {
|
||||
case QAudioDecoder::DecodingState:
|
||||
m_cout << "Decoding..." << endl;
|
||||
break;
|
||||
case QAudioDecoder::StoppedState:
|
||||
m_cout << "Decoding stopped" << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AudioDecoder::finished()
|
||||
{
|
||||
if (!m_fileWriter.close())
|
||||
m_cout << "Failed to finilize output file" << endl;
|
||||
|
||||
m_cout << "Decoding finished" << endl;
|
||||
|
||||
if (m_isPlayback) {
|
||||
m_cout << "Starting playback" << endl;
|
||||
m_soundEffect.setSource(QUrl::fromLocalFile(m_targetFilename));
|
||||
m_soundEffect.play();
|
||||
} else {
|
||||
emit done();
|
||||
}
|
||||
}
|
||||
|
||||
void AudioDecoder::playbackStatusChanged()
|
||||
{
|
||||
if (m_soundEffect.status() == QSoundEffect::Error) {
|
||||
m_cout << "Playback error" << endl;
|
||||
emit done();
|
||||
}
|
||||
}
|
||||
|
||||
void AudioDecoder::playingChanged()
|
||||
{
|
||||
if (!m_soundEffect.isPlaying()) {
|
||||
m_cout << "Playback finished" << endl;
|
||||
if (m_isDelete)
|
||||
QFile::remove(m_targetFilename);
|
||||
emit done();
|
||||
}
|
||||
}
|
||||
|
||||
void AudioDecoder::updateProgress()
|
||||
{
|
||||
qint64 position = m_decoder.position();
|
||||
qint64 duration = m_decoder.duration();
|
||||
qreal progress = m_progress;
|
||||
if (position >= 0 && duration > 0)
|
||||
progress = position / (qreal)duration;
|
||||
|
||||
if (progress > m_progress + 0.1) {
|
||||
m_cout << "Decoding progress: " << (int)(progress * 100.0) << "%" << endl;
|
||||
m_progress = progress;
|
||||
}
|
||||
}
|
||||
92
examples/multimedia/audiodecoder/audiodecoder.h
Normal file
92
examples/multimedia/audiodecoder/audiodecoder.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef AUDIODECODER_H
|
||||
#define AUDIODECODER_H
|
||||
|
||||
#include "wavefilewriter.h"
|
||||
|
||||
#include <QAudioDecoder>
|
||||
#include <QSoundEffect>
|
||||
#include <QTextStream>
|
||||
|
||||
class AudioDecoder : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AudioDecoder(bool isPlayback, bool isDelete);
|
||||
~AudioDecoder() { }
|
||||
|
||||
void setSourceFilename(const QString &fileName);
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
void setTargetFilename(const QString &fileName);
|
||||
|
||||
signals:
|
||||
void done();
|
||||
|
||||
public slots:
|
||||
void bufferReady();
|
||||
void error(QAudioDecoder::Error error);
|
||||
void stateChanged(QAudioDecoder::State newState);
|
||||
void finished();
|
||||
|
||||
void playbackStatusChanged();
|
||||
void playingChanged();
|
||||
|
||||
private slots:
|
||||
void updateProgress();
|
||||
|
||||
private:
|
||||
bool m_isPlayback;
|
||||
bool m_isDelete;
|
||||
QAudioDecoder m_decoder;
|
||||
QTextStream m_cout;
|
||||
|
||||
QString m_targetFilename;
|
||||
WaveFileWriter m_fileWriter;
|
||||
QSoundEffect m_soundEffect;
|
||||
|
||||
qreal m_progress;
|
||||
};
|
||||
|
||||
#endif // AUDIODECODER_H
|
||||
17
examples/multimedia/audiodecoder/audiodecoder.pro
Normal file
17
examples/multimedia/audiodecoder/audiodecoder.pro
Normal file
@@ -0,0 +1,17 @@
|
||||
TEMPLATE = app
|
||||
TARGET = audiodecoder
|
||||
|
||||
CONFIG += qt warn_on
|
||||
|
||||
HEADERS = \
|
||||
audiodecoder.h \
|
||||
wavefilewriter.h
|
||||
SOURCES = main.cpp \
|
||||
audiodecoder.cpp \
|
||||
wavefilewriter.cpp
|
||||
|
||||
QT += multimedia
|
||||
CONFIG += console
|
||||
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/audiodecoder
|
||||
INSTALLS += target
|
||||
94
examples/multimedia/audiodecoder/main.cpp
Normal file
94
examples/multimedia/audiodecoder/main.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "audiodecoder.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QTextStream>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
|
||||
QTextStream cout(stdout, QIODevice::WriteOnly);
|
||||
if (app.arguments().size() < 2) {
|
||||
cout << "Usage: audiodecoder [-p] [-pd] SOURCEFILE [TARGETFILE]" << endl;
|
||||
cout << "Set -p option if you want to play output file." << endl;
|
||||
cout << "Set -pd option if you want to play output file and delete it after successful playback." << endl;
|
||||
cout << "Default TARGETFILE name is \"out.wav\" in the same directory as the source file." << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool isPlayback = false;
|
||||
bool isDelete = false;
|
||||
|
||||
if (app.arguments().at(1) == "-p")
|
||||
isPlayback = true;
|
||||
else if (app.arguments().at(1) == "-pd") {
|
||||
isPlayback = true;
|
||||
isDelete = true;
|
||||
}
|
||||
|
||||
QFileInfo sourceFile;
|
||||
QFileInfo targetFile;
|
||||
|
||||
int sourceFileIndex = (isPlayback || isDelete) ? 2 : 1;
|
||||
if (app.arguments().size() <= sourceFileIndex) {
|
||||
cout << "Error: source filename is not specified." << endl;
|
||||
return 0;
|
||||
}
|
||||
sourceFile.setFile(app.arguments().at(sourceFileIndex));
|
||||
if (app.arguments().size() > sourceFileIndex + 1)
|
||||
targetFile.setFile(app.arguments().at(sourceFileIndex + 1));
|
||||
else
|
||||
targetFile.setFile(sourceFile.dir().absoluteFilePath("out.wav"));
|
||||
|
||||
AudioDecoder decoder(isPlayback, isDelete);
|
||||
QObject::connect(&decoder, SIGNAL(done()), &app, SLOT(quit()));
|
||||
decoder.setSourceFilename(sourceFile.absoluteFilePath());
|
||||
decoder.setTargetFilename(targetFile.absoluteFilePath());
|
||||
decoder.start();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
192
examples/multimedia/audiodecoder/wavefilewriter.cpp
Normal file
192
examples/multimedia/audiodecoder/wavefilewriter.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "wavefilewriter.h"
|
||||
|
||||
struct Q_PACKED chunk
|
||||
{
|
||||
char id[4];
|
||||
quint32 size;
|
||||
};
|
||||
|
||||
struct Q_PACKED RIFFHeader
|
||||
{
|
||||
chunk descriptor; // "RIFF"
|
||||
char type[4]; // "WAVE"
|
||||
};
|
||||
|
||||
struct Q_PACKED WAVEHeader
|
||||
{
|
||||
chunk descriptor;
|
||||
quint16 audioFormat;
|
||||
quint16 numChannels;
|
||||
quint32 sampleRate;
|
||||
quint32 byteRate;
|
||||
quint16 blockAlign;
|
||||
quint16 bitsPerSample;
|
||||
};
|
||||
|
||||
struct Q_PACKED DATAHeader
|
||||
{
|
||||
chunk descriptor;
|
||||
};
|
||||
|
||||
struct Q_PACKED CombinedHeader
|
||||
{
|
||||
RIFFHeader riff;
|
||||
WAVEHeader wave;
|
||||
DATAHeader data;
|
||||
};
|
||||
static const int HeaderLength = sizeof(CombinedHeader);
|
||||
|
||||
|
||||
WaveFileWriter::WaveFileWriter(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_dataLength(0)
|
||||
{
|
||||
}
|
||||
|
||||
WaveFileWriter::~WaveFileWriter()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
bool WaveFileWriter::open(const QString& fileName, const QAudioFormat& format)
|
||||
{
|
||||
if (file.isOpen())
|
||||
return false; // file already open
|
||||
|
||||
if (format.codec() != "audio/pcm" || format.sampleType() != QAudioFormat::SignedInt)
|
||||
return false; // data format is not supported
|
||||
|
||||
file.setFileName(fileName);
|
||||
if (!file.open(QIODevice::WriteOnly))
|
||||
return false; // unable to open file for writing
|
||||
|
||||
if (!writeHeader(format))
|
||||
return false;
|
||||
|
||||
m_format = format;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WaveFileWriter::write(const QAudioBuffer &buffer)
|
||||
{
|
||||
if (buffer.format() != m_format)
|
||||
return false; // buffer format has changed
|
||||
|
||||
qint64 written = file.write((const char *)buffer.constData(), buffer.byteCount());
|
||||
m_dataLength += written;
|
||||
return written == buffer.byteCount();
|
||||
}
|
||||
|
||||
bool WaveFileWriter::close()
|
||||
{
|
||||
bool result = false;
|
||||
if (file.isOpen()) {
|
||||
Q_ASSERT(m_dataLength < INT_MAX);
|
||||
result = writeDataLength();
|
||||
|
||||
m_dataLength = 0;
|
||||
file.close();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool WaveFileWriter::writeHeader(const QAudioFormat &format)
|
||||
{
|
||||
// check if format is supported
|
||||
if (format.byteOrder() == QAudioFormat::BigEndian || format.sampleType() != QAudioFormat::SignedInt)
|
||||
return false;
|
||||
|
||||
CombinedHeader header;
|
||||
memset(&header, 0, HeaderLength);
|
||||
|
||||
#ifndef Q_LITTLE_ENDIAN
|
||||
// only implemented for LITTLE ENDIAN
|
||||
return false;
|
||||
#else
|
||||
// RIFF header
|
||||
memcpy(header.riff.descriptor.id, "RIFF", 4);
|
||||
header.riff.descriptor.size = 0; // this will be updated with correct duration:
|
||||
// m_dataLength + HeaderLength - 8
|
||||
// WAVE header
|
||||
memcpy(header.riff.type, "WAVE", 4);
|
||||
memcpy(header.wave.descriptor.id, "fmt ", 4);
|
||||
header.wave.descriptor.size = quint32(16);
|
||||
header.wave.audioFormat = quint16(1);
|
||||
header.wave.numChannels = quint16(format.channelCount());
|
||||
header.wave.sampleRate = quint32(format.sampleRate());
|
||||
header.wave.byteRate = quint32(format.sampleRate() * format.channelCount() * format.sampleSize() / 8);
|
||||
header.wave.blockAlign = quint16(format.channelCount() * format.sampleSize() / 8);
|
||||
header.wave.bitsPerSample = quint16(format.sampleSize());
|
||||
|
||||
// DATA header
|
||||
memcpy(header.data.descriptor.id,"data", 4);
|
||||
header.data.descriptor.size = 0; // this will be updated with correct data length: m_dataLength
|
||||
|
||||
return (file.write(reinterpret_cast<const char *>(&header), HeaderLength) == HeaderLength);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool WaveFileWriter::writeDataLength()
|
||||
{
|
||||
#ifndef Q_LITTLE_ENDIAN
|
||||
// only implemented for LITTLE ENDIAN
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (file.isSequential())
|
||||
return false;
|
||||
|
||||
// seek to RIFF header size, see header.riff.descriptor.size above
|
||||
if (!file.seek(4))
|
||||
return false;
|
||||
|
||||
quint32 length = m_dataLength + HeaderLength - 8;
|
||||
if (file.write(reinterpret_cast<const char *>(&length), 4) != 4)
|
||||
return false;
|
||||
|
||||
// seek to DATA header size, see header.data.descriptor.size above
|
||||
if (!file.seek(40))
|
||||
return false;
|
||||
|
||||
return file.write(reinterpret_cast<const char *>(&m_dataLength), 4) == 4;
|
||||
}
|
||||
70
examples/multimedia/audiodecoder/wavefilewriter.h
Normal file
70
examples/multimedia/audiodecoder/wavefilewriter.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef WAVEFILEWRITER_H
|
||||
#define WAVEFILEWRITER_H
|
||||
|
||||
#include <QAudioBuffer>
|
||||
#include <QFile>
|
||||
#include <QObject>
|
||||
|
||||
class WaveFileWriter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit WaveFileWriter(QObject *parent = 0);
|
||||
~WaveFileWriter();
|
||||
|
||||
bool open(const QString &fileName, const QAudioFormat &format);
|
||||
bool write(const QAudioBuffer &buffer);
|
||||
bool close();
|
||||
bool isOpen() const { return file.isOpen(); }
|
||||
|
||||
private:
|
||||
bool writeHeader(const QAudioFormat &format);
|
||||
bool writeDataLength();
|
||||
|
||||
QFile file;
|
||||
QAudioFormat m_format;
|
||||
qint64 m_dataLength;
|
||||
};
|
||||
|
||||
#endif // WAVEFILEWRITER_H
|
||||
311
examples/multimedia/audiodevices/audiodevices.cpp
Normal file
311
examples/multimedia/audiodevices/audiodevices.cpp
Normal file
@@ -0,0 +1,311 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "audiodevices.h"
|
||||
|
||||
// Utility functions for converting QAudioFormat fields into text
|
||||
|
||||
static QString toString(QAudioFormat::SampleType sampleType)
|
||||
{
|
||||
QString result("Unknown");
|
||||
switch (sampleType) {
|
||||
case QAudioFormat::SignedInt:
|
||||
result = "SignedInt";
|
||||
break;
|
||||
case QAudioFormat::UnSignedInt:
|
||||
result = "UnSignedInt";
|
||||
break;
|
||||
case QAudioFormat::Float:
|
||||
result = "Float";
|
||||
break;
|
||||
case QAudioFormat::Unknown:
|
||||
result = "Unknown";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static QString toString(QAudioFormat::Endian endian)
|
||||
{
|
||||
QString result("Unknown");
|
||||
switch (endian) {
|
||||
case QAudioFormat::LittleEndian:
|
||||
result = "LittleEndian";
|
||||
break;
|
||||
case QAudioFormat::BigEndian:
|
||||
result = "BigEndian";
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
AudioDevicesBase::AudioDevicesBase(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
{
|
||||
setupUi(this);
|
||||
}
|
||||
|
||||
AudioDevicesBase::~AudioDevicesBase() {}
|
||||
|
||||
|
||||
AudioTest::AudioTest(QWidget *parent)
|
||||
: AudioDevicesBase(parent)
|
||||
{
|
||||
mode = QAudio::AudioOutput;
|
||||
|
||||
connect(testButton, SIGNAL(clicked()), SLOT(test()));
|
||||
connect(modeBox, SIGNAL(activated(int)), SLOT(modeChanged(int)));
|
||||
connect(deviceBox, SIGNAL(activated(int)), SLOT(deviceChanged(int)));
|
||||
connect(sampleRateBox, SIGNAL(activated(int)), SLOT(sampleRateChanged(int)));
|
||||
connect(channelsBox, SIGNAL(activated(int)), SLOT(channelChanged(int)));
|
||||
connect(codecsBox, SIGNAL(activated(int)), SLOT(codecChanged(int)));
|
||||
connect(sampleSizesBox, SIGNAL(activated(int)), SLOT(sampleSizeChanged(int)));
|
||||
connect(sampleTypesBox, SIGNAL(activated(int)), SLOT(sampleTypeChanged(int)));
|
||||
connect(endianBox, SIGNAL(activated(int)), SLOT(endianChanged(int)));
|
||||
connect(populateTableButton, SIGNAL(clicked()), SLOT(populateTable()));
|
||||
|
||||
modeBox->setCurrentIndex(0);
|
||||
modeChanged(0);
|
||||
deviceBox->setCurrentIndex(0);
|
||||
deviceChanged(0);
|
||||
}
|
||||
|
||||
AudioTest::~AudioTest()
|
||||
{
|
||||
}
|
||||
|
||||
void AudioTest::test()
|
||||
{
|
||||
// tries to set all the settings picked.
|
||||
testResult->clear();
|
||||
|
||||
if (!deviceInfo.isNull()) {
|
||||
if (deviceInfo.isFormatSupported(settings)) {
|
||||
testResult->setText(tr("Success"));
|
||||
nearestSampleRate->setText("");
|
||||
nearestChannel->setText("");
|
||||
nearestCodec->setText("");
|
||||
nearestSampleSize->setText("");
|
||||
nearestSampleType->setText("");
|
||||
nearestEndian->setText("");
|
||||
} else {
|
||||
QAudioFormat nearest = deviceInfo.nearestFormat(settings);
|
||||
testResult->setText(tr("Failed"));
|
||||
nearestSampleRate->setText(QString("%1").arg(nearest.sampleRate()));
|
||||
nearestChannel->setText(QString("%1").arg(nearest.channelCount()));
|
||||
nearestCodec->setText(nearest.codec());
|
||||
nearestSampleSize->setText(QString("%1").arg(nearest.sampleSize()));
|
||||
nearestSampleType->setText(toString(nearest.sampleType()));
|
||||
nearestEndian->setText(toString(nearest.byteOrder()));
|
||||
}
|
||||
}
|
||||
else
|
||||
testResult->setText(tr("No Device"));
|
||||
}
|
||||
|
||||
void AudioTest::modeChanged(int idx)
|
||||
{
|
||||
testResult->clear();
|
||||
|
||||
// mode has changed
|
||||
if (idx == 0)
|
||||
mode = QAudio::AudioInput;
|
||||
else
|
||||
mode = QAudio::AudioOutput;
|
||||
|
||||
deviceBox->clear();
|
||||
foreach (const QAudioDeviceInfo &deviceInfo, QAudioDeviceInfo::availableDevices(mode))
|
||||
deviceBox->addItem(deviceInfo.deviceName(), qVariantFromValue(deviceInfo));
|
||||
|
||||
deviceBox->setCurrentIndex(0);
|
||||
deviceChanged(0);
|
||||
}
|
||||
|
||||
void AudioTest::deviceChanged(int idx)
|
||||
{
|
||||
testResult->clear();
|
||||
|
||||
if (deviceBox->count() == 0)
|
||||
return;
|
||||
|
||||
// device has changed
|
||||
deviceInfo = deviceBox->itemData(idx).value<QAudioDeviceInfo>();
|
||||
|
||||
sampleRateBox->clear();
|
||||
QList<int> sampleRatez = deviceInfo.supportedSampleRates();
|
||||
for (int i = 0; i < sampleRatez.size(); ++i)
|
||||
sampleRateBox->addItem(QString("%1").arg(sampleRatez.at(i)));
|
||||
if (sampleRatez.size())
|
||||
settings.setSampleRate(sampleRatez.at(0));
|
||||
|
||||
channelsBox->clear();
|
||||
QList<int> chz = deviceInfo.supportedChannelCounts();
|
||||
for (int i = 0; i < chz.size(); ++i)
|
||||
channelsBox->addItem(QString("%1").arg(chz.at(i)));
|
||||
if (chz.size())
|
||||
settings.setChannelCount(chz.at(0));
|
||||
|
||||
codecsBox->clear();
|
||||
QStringList codecs = deviceInfo.supportedCodecs();
|
||||
for (int i = 0; i < codecs.size(); ++i)
|
||||
codecsBox->addItem(QString("%1").arg(codecs.at(i)));
|
||||
if (codecs.size())
|
||||
settings.setCodec(codecs.at(0));
|
||||
// Add false to create failed condition!
|
||||
codecsBox->addItem("audio/test");
|
||||
|
||||
sampleSizesBox->clear();
|
||||
QList<int> sampleSizez = deviceInfo.supportedSampleSizes();
|
||||
for (int i = 0; i < sampleSizez.size(); ++i)
|
||||
sampleSizesBox->addItem(QString("%1").arg(sampleSizez.at(i)));
|
||||
if (sampleSizez.size())
|
||||
settings.setSampleSize(sampleSizez.at(0));
|
||||
|
||||
sampleTypesBox->clear();
|
||||
QList<QAudioFormat::SampleType> sampleTypez = deviceInfo.supportedSampleTypes();
|
||||
|
||||
for (int i = 0; i < sampleTypez.size(); ++i)
|
||||
sampleTypesBox->addItem(toString(sampleTypez.at(i)));
|
||||
if (sampleTypez.size())
|
||||
settings.setSampleType(sampleTypez.at(0));
|
||||
|
||||
endianBox->clear();
|
||||
QList<QAudioFormat::Endian> endianz = deviceInfo.supportedByteOrders();
|
||||
for (int i = 0; i < endianz.size(); ++i)
|
||||
endianBox->addItem(toString(endianz.at(i)));
|
||||
if (endianz.size())
|
||||
settings.setByteOrder(endianz.at(0));
|
||||
|
||||
allFormatsTable->clearContents();
|
||||
}
|
||||
|
||||
void AudioTest::populateTable()
|
||||
{
|
||||
int row = 0;
|
||||
|
||||
QAudioFormat format;
|
||||
foreach (QString codec, deviceInfo.supportedCodecs()) {
|
||||
format.setCodec(codec);
|
||||
foreach (int sampleRate, deviceInfo.supportedSampleRates()) {
|
||||
format.setSampleRate(sampleRate);
|
||||
foreach (int channels, deviceInfo.supportedChannelCounts()) {
|
||||
format.setChannelCount(channels);
|
||||
foreach (QAudioFormat::SampleType sampleType, deviceInfo.supportedSampleTypes()) {
|
||||
format.setSampleType(sampleType);
|
||||
foreach (int sampleSize, deviceInfo.supportedSampleSizes()) {
|
||||
format.setSampleSize(sampleSize);
|
||||
foreach (QAudioFormat::Endian endian, deviceInfo.supportedByteOrders()) {
|
||||
format.setByteOrder(endian);
|
||||
if (deviceInfo.isFormatSupported(format)) {
|
||||
allFormatsTable->setRowCount(row + 1);
|
||||
|
||||
QTableWidgetItem *codecItem = new QTableWidgetItem(format.codec());
|
||||
allFormatsTable->setItem(row, 0, codecItem);
|
||||
|
||||
QTableWidgetItem *sampleRateItem = new QTableWidgetItem(QString("%1").arg(format.sampleRate()));
|
||||
allFormatsTable->setItem(row, 1, sampleRateItem);
|
||||
|
||||
QTableWidgetItem *channelsItem = new QTableWidgetItem(QString("%1").arg(format.channelCount()));
|
||||
allFormatsTable->setItem(row, 2, channelsItem);
|
||||
|
||||
QTableWidgetItem *sampleTypeItem = new QTableWidgetItem(toString(format.sampleType()));
|
||||
allFormatsTable->setItem(row, 3, sampleTypeItem);
|
||||
|
||||
QTableWidgetItem *sampleSizeItem = new QTableWidgetItem(QString("%1").arg(format.sampleSize()));
|
||||
allFormatsTable->setItem(row, 4, sampleSizeItem);
|
||||
|
||||
QTableWidgetItem *byteOrderItem = new QTableWidgetItem(toString(format.byteOrder()));
|
||||
allFormatsTable->setItem(row, 5, byteOrderItem);
|
||||
|
||||
++row;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AudioTest::sampleRateChanged(int idx)
|
||||
{
|
||||
// sample rate has changed
|
||||
settings.setSampleRate(sampleRateBox->itemText(idx).toInt());
|
||||
}
|
||||
|
||||
void AudioTest::channelChanged(int idx)
|
||||
{
|
||||
settings.setChannelCount(channelsBox->itemText(idx).toInt());
|
||||
}
|
||||
|
||||
void AudioTest::codecChanged(int idx)
|
||||
{
|
||||
settings.setCodec(codecsBox->itemText(idx));
|
||||
}
|
||||
|
||||
void AudioTest::sampleSizeChanged(int idx)
|
||||
{
|
||||
settings.setSampleSize(sampleSizesBox->itemText(idx).toInt());
|
||||
}
|
||||
|
||||
void AudioTest::sampleTypeChanged(int idx)
|
||||
{
|
||||
switch (sampleTypesBox->itemText(idx).toInt()) {
|
||||
case QAudioFormat::SignedInt:
|
||||
settings.setSampleType(QAudioFormat::SignedInt);
|
||||
break;
|
||||
case QAudioFormat::UnSignedInt:
|
||||
settings.setSampleType(QAudioFormat::UnSignedInt);
|
||||
break;
|
||||
case QAudioFormat::Float:
|
||||
settings.setSampleType(QAudioFormat::Float);
|
||||
}
|
||||
}
|
||||
|
||||
void AudioTest::endianChanged(int idx)
|
||||
{
|
||||
switch (endianBox->itemText(idx).toInt()) {
|
||||
case QAudioFormat::LittleEndian:
|
||||
settings.setByteOrder(QAudioFormat::LittleEndian);
|
||||
break;
|
||||
case QAudioFormat::BigEndian:
|
||||
settings.setByteOrder(QAudioFormat::BigEndian);
|
||||
}
|
||||
}
|
||||
84
examples/multimedia/audiodevices/audiodevices.h
Normal file
84
examples/multimedia/audiodevices/audiodevices.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef AUDIODEVICES_H
|
||||
#define AUDIODEVICES_H
|
||||
|
||||
#include <QAudioDeviceInfo>
|
||||
#include <QMainWindow>
|
||||
#include <QObject>
|
||||
|
||||
#include "ui_audiodevicesbase.h"
|
||||
|
||||
class AudioDevicesBase : public QMainWindow, public Ui::AudioDevicesBase
|
||||
{
|
||||
public:
|
||||
AudioDevicesBase(QWidget *parent = 0);
|
||||
virtual ~AudioDevicesBase();
|
||||
};
|
||||
|
||||
class AudioTest : public AudioDevicesBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AudioTest(QWidget *parent = 0);
|
||||
virtual ~AudioTest();
|
||||
|
||||
QAudioDeviceInfo deviceInfo;
|
||||
QAudioFormat settings;
|
||||
QAudio::Mode mode;
|
||||
|
||||
private slots:
|
||||
void modeChanged(int idx);
|
||||
void deviceChanged(int idx);
|
||||
void sampleRateChanged(int idx);
|
||||
void channelChanged(int idx);
|
||||
void codecChanged(int idx);
|
||||
void sampleSizeChanged(int idx);
|
||||
void sampleTypeChanged(int idx);
|
||||
void endianChanged(int idx);
|
||||
void test();
|
||||
void populateTable();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
16
examples/multimedia/audiodevices/audiodevices.pro
Normal file
16
examples/multimedia/audiodevices/audiodevices.pro
Normal file
@@ -0,0 +1,16 @@
|
||||
TEMPLATE = app
|
||||
TARGET = audiodevices
|
||||
|
||||
QT += multimedia
|
||||
|
||||
HEADERS = audiodevices.h
|
||||
|
||||
SOURCES = audiodevices.cpp \
|
||||
main.cpp
|
||||
|
||||
FORMS += audiodevicesbase.ui
|
||||
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/audiodevices
|
||||
INSTALLS += target
|
||||
|
||||
QT+=widgets
|
||||
390
examples/multimedia/audiodevices/audiodevicesbase.ui
Normal file
390
examples/multimedia/audiodevices/audiodevicesbase.ui
Normal file
@@ -0,0 +1,390 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AudioDevicesBase</class>
|
||||
<widget class="QMainWindow" name="AudioDevicesBase">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>679</width>
|
||||
<height>598</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Audio Devices</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>659</width>
|
||||
<height>558</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="modeLabel">
|
||||
<property name="text">
|
||||
<string>Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="deviceLabel">
|
||||
<property name="text">
|
||||
<string>Device</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QComboBox" name="modeBox">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Input</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Output</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="deviceBox"/>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="testFormatTab">
|
||||
<attribute name="title">
|
||||
<string>Test format</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="actualLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><i>Actual Settings</i></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="nearestLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">Nearest Settings</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="sampleRateBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLineEdit" name="nearestSampleRate">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QComboBox" name="channelsBox"/>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QLineEdit" name="nearestChannel">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QComboBox" name="sampleSizesBox"/>
|
||||
</item>
|
||||
<item row="9" column="2">
|
||||
<widget class="QLineEdit" name="nearestSampleSize">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="1">
|
||||
<widget class="QComboBox" name="endianBox"/>
|
||||
</item>
|
||||
<item row="14" column="2">
|
||||
<widget class="QLineEdit" name="nearestEndian">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="1">
|
||||
<widget class="QPushButton" name="testButton">
|
||||
<property name="text">
|
||||
<string>Test</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="2">
|
||||
<widget class="QLabel" name="testResult">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="actualFreqLabel">
|
||||
<property name="text">
|
||||
<string>Frequency (Hz)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="actualChannelLabel">
|
||||
<property name="text">
|
||||
<string>Channels</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="actualSampleSizeLabel">
|
||||
<property name="text">
|
||||
<string>Sample size (bits)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="0">
|
||||
<widget class="QLabel" name="actualEndianLabel">
|
||||
<property name="text">
|
||||
<string>Endianess</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="0" colspan="3">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Note: an invalid codec 'audio/test' exists in order to allow an invalid format to be constructed, and therefore to trigger a 'nearest format' calculation.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="actualCodecLabel">
|
||||
<property name="text">
|
||||
<string>Codec</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLineEdit" name="nearestCodec">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="codecsBox"/>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="actualSampleTypeLabel">
|
||||
<property name="text">
|
||||
<string>SampleType</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QComboBox" name="sampleTypesBox"/>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<widget class="QLineEdit" name="nearestSampleType">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>All formats</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="populateTableButton">
|
||||
<property name="text">
|
||||
<string>Populate table</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableWidget" name="allFormatsTable">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="dragDropOverwriteMode">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectItems</enum>
|
||||
</property>
|
||||
<property name="textElideMode">
|
||||
<enum>Qt::ElideNone</enum>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="cornerButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderHighlightSections">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderHighlightSections">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Codec</string>
|
||||
</property>
|
||||
<property name="textAlignment">
|
||||
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Frequency (Hz)</string>
|
||||
</property>
|
||||
<property name="textAlignment">
|
||||
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Channels</string>
|
||||
</property>
|
||||
<property name="textAlignment">
|
||||
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Sample type</string>
|
||||
</property>
|
||||
<property name="textAlignment">
|
||||
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Sample size (bits)</string>
|
||||
</property>
|
||||
<property name="textAlignment">
|
||||
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Endianness</string>
|
||||
</property>
|
||||
<property name="textAlignment">
|
||||
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
BIN
examples/multimedia/audiodevices/doc/images/audiodevices.png
Normal file
BIN
examples/multimedia/audiodevices/doc/images/audiodevices.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 37 KiB |
43
examples/multimedia/audiodevices/doc/src/audiodevices.qdoc
Normal file
43
examples/multimedia/audiodevices/doc/src/audiodevices.qdoc
Normal file
@@ -0,0 +1,43 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:FDL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Free Documentation License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Free
|
||||
** Documentation License version 1.3 as published by the Free Software
|
||||
** Foundation and appearing in the file included in the packaging of
|
||||
** this file. Please review the following information to ensure
|
||||
** the GNU Free Documentation License version 1.3 requirements
|
||||
** will be met: http://www.gnu.org/copyleft/fdl.html.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\example audiodevices
|
||||
\title Audio Devices Example
|
||||
\ingroup audio_examples
|
||||
\brief The Audio Devices example shows the application of the audio devices APIs
|
||||
|
||||
|
||||
This example shows how to create a simple application to list and test
|
||||
the configuration for the various audio devices available on the device
|
||||
or machine. This is done using the QtMobility Multimedia API.
|
||||
|
||||
\image audiodevices.png
|
||||
|
||||
*/
|
||||
|
||||
|
||||
54
examples/multimedia/audiodevices/main.cpp
Normal file
54
examples/multimedia/audiodevices/main.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "audiodevices.h"
|
||||
|
||||
int main(int argv, char **args)
|
||||
{
|
||||
QApplication app(argv, args);
|
||||
app.setApplicationName("Audio Device Test");
|
||||
|
||||
AudioTest audio;
|
||||
audio.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
6
examples/multimedia/audioengine/audioengine.pro
Normal file
6
examples/multimedia/audioengine/audioengine.pro
Normal file
@@ -0,0 +1,6 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
# These examples contain no C++ and can simply be copied
|
||||
SUBDIRS =
|
||||
EXAMPLE_FILES = qml
|
||||
|
||||
39
examples/multimedia/audioengine/doc/src/audioengine.qdoc
Normal file
39
examples/multimedia/audioengine/doc/src/audioengine.qdoc
Normal file
@@ -0,0 +1,39 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:FDL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Free Documentation License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Free
|
||||
** Documentation License version 1.3 as published by the Free Software
|
||||
** Foundation and appearing in the file included in the packaging of
|
||||
** this file. Please review the following information to ensure
|
||||
** the GNU Free Documentation License version 1.3 requirements
|
||||
** will be met: http://www.gnu.org/copyleft/fdl.html.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\example audioengine
|
||||
\title AudioEngine Example
|
||||
\ingroup audioengine_examples
|
||||
\brief The Audio Engine example demonstrates 3D sound control using
|
||||
the QtAudioEngine API.
|
||||
|
||||
\image audioengine.png
|
||||
|
||||
*/
|
||||
|
||||
|
||||
193
examples/multimedia/audioengine/qml/audioengine.qml
Normal file
193
examples/multimedia/audioengine/qml/audioengine.qml
Normal file
@@ -0,0 +1,193 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtAudioEngine 1.0
|
||||
import QtQuick 2.0
|
||||
import "content"
|
||||
|
||||
Rectangle {
|
||||
color:"white"
|
||||
id: root
|
||||
width: 300
|
||||
height: 500
|
||||
property int radius : 100
|
||||
property real twoPi : Math.PI + Math.PI
|
||||
|
||||
MyAudioEngine {
|
||||
id:audioEngine
|
||||
listener.position : Qt.vector3d(observer.x, observer.y, 0);
|
||||
}
|
||||
|
||||
Item {
|
||||
id: circle
|
||||
x: root.width / 2
|
||||
y: root.height / 2
|
||||
property real percent: 0
|
||||
SequentialAnimation on percent {
|
||||
id: circleAnim1
|
||||
loops: Animation.Infinite
|
||||
running: true
|
||||
NumberAnimation {
|
||||
duration: 8000
|
||||
from: 0
|
||||
to: 1
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: holder
|
||||
x: circle.x - Math.sin(circle.percent * root.twoPi) * root.radius - 50
|
||||
y: circle.y + Math.cos(circle.percent * root.twoPi) * root.radius + 50
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
color:"green"
|
||||
id: observer
|
||||
width: 16
|
||||
height: 16
|
||||
x: circle.x - width / 2
|
||||
y: circle.y - height / 2
|
||||
}
|
||||
Rectangle {
|
||||
color:"red"
|
||||
id: starship
|
||||
width: 32
|
||||
height: 32
|
||||
x: holder.x - width / 2
|
||||
y: holder.y - height / 2
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
audioEngine.sounds["effects"].play(Qt.vector3d(holder.x, holder.y, 0));
|
||||
}
|
||||
}
|
||||
|
||||
SoundInstance {
|
||||
id: shipSound
|
||||
engine:audioEngine
|
||||
sound:"shipengine"
|
||||
position: Qt.vector3d(holder.x, holder.y, 0)
|
||||
direction: {
|
||||
var a = (starship.rotation / 360) * root.twoPi;
|
||||
return Qt.vector3d(Math.sin(a), -Math.cos(a), 0);
|
||||
}
|
||||
velocity: {
|
||||
var speed = root.twoPi * root.radius / 4;
|
||||
return shipSound.direction * speed;
|
||||
}
|
||||
|
||||
Component.onCompleted: shipSound.play()
|
||||
}
|
||||
|
||||
//Category Volume Control
|
||||
Rectangle {
|
||||
property variant volumeCtrl: audioEngine.categories["sfx"];
|
||||
id: volumeBar
|
||||
x: 10
|
||||
y: 10
|
||||
width: 280
|
||||
height: 22
|
||||
color: "darkgray"
|
||||
Rectangle {
|
||||
id: volumeTracker
|
||||
x: 0
|
||||
y: 0
|
||||
width: volumeBar.volumeCtrl.volume * parent.width;
|
||||
height: parent.height
|
||||
color: "lightgreen"
|
||||
}
|
||||
Text {
|
||||
text: " volume:" + volumeBar.volumeCtrl.volume * 100 +"%";
|
||||
font.pointSize: 16;
|
||||
font.italic: true;
|
||||
color: "black"
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
property bool m:false
|
||||
onPressed: {
|
||||
m = true;
|
||||
updateVolume(mouse);
|
||||
}
|
||||
onReleased: {
|
||||
m = false;
|
||||
}
|
||||
|
||||
onPositionChanged: {
|
||||
if (m) {
|
||||
updateVolume(mouse);
|
||||
}
|
||||
}
|
||||
function updateVolume(mouse) {
|
||||
volumeBar.volumeCtrl.volume = Math.min(1, Math.max(0, mouse.x / (volumeBar.width - 1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Information display
|
||||
Item {
|
||||
x:10
|
||||
y:32
|
||||
Text {
|
||||
text: " [live instances] = " + audioEngine.liveInstances;
|
||||
font.pointSize: 14;
|
||||
font.italic: true;
|
||||
color: "black"
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
x:10
|
||||
y:60
|
||||
Text {
|
||||
text: " [loading]=" + (audioEngine.loading ? "true" : "false");
|
||||
font.pointSize: 16;
|
||||
font.italic: true;
|
||||
color: "black"
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
16
examples/multimedia/audioengine/qml/audioengine.qmlproject
Normal file
16
examples/multimedia/audioengine/qml/audioengine.qmlproject
Normal file
@@ -0,0 +1,16 @@
|
||||
import QmlProject 1.1
|
||||
|
||||
Project {
|
||||
mainFile: "audioengine.qml"
|
||||
|
||||
/* Include .qml, .js, and image files from current directory and subdirectories */
|
||||
QmlFiles {
|
||||
directory: "."
|
||||
}
|
||||
JavaScriptFiles {
|
||||
directory: "."
|
||||
}
|
||||
ImageFiles {
|
||||
directory: "."
|
||||
}
|
||||
}
|
||||
131
examples/multimedia/audioengine/qml/content/MyAudioEngine.qml
Normal file
131
examples/multimedia/audioengine/qml/content/MyAudioEngine.qml
Normal file
@@ -0,0 +1,131 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtAudioEngine 1.0
|
||||
import QtQuick 2.0
|
||||
|
||||
AudioEngine {
|
||||
|
||||
AudioCategory {
|
||||
name:"sfx"
|
||||
volume: 1
|
||||
}
|
||||
|
||||
AudioCategory {
|
||||
name:"music"
|
||||
volume: 1
|
||||
}
|
||||
|
||||
|
||||
AttenuationModelInverse {
|
||||
name:"default"
|
||||
start: 20
|
||||
end: 1000
|
||||
rolloff: 1
|
||||
}
|
||||
|
||||
AttenuationModelLinear {
|
||||
name:"shipengine"
|
||||
start: 20
|
||||
end: 180
|
||||
}
|
||||
|
||||
AudioSample {
|
||||
name:"fire"
|
||||
source: "fire-03-loop.wav"
|
||||
preloaded:true
|
||||
}
|
||||
|
||||
AudioSample {
|
||||
name:"explosion"
|
||||
source: "explosion-02.wav"
|
||||
}
|
||||
AudioSample {
|
||||
name:"lava"
|
||||
source: "lava-bubbling-01.wav"
|
||||
}
|
||||
AudioSample {
|
||||
name:"water"
|
||||
source: "running-water-01.wav"
|
||||
}
|
||||
Sound {
|
||||
name:"shipengine"
|
||||
attenuationModel:"shipengine"
|
||||
category:"sfx"
|
||||
PlayVariation {
|
||||
looping:true
|
||||
sample:"fire"
|
||||
maxGain:0.9
|
||||
minGain:0.8
|
||||
}
|
||||
}
|
||||
|
||||
Sound {
|
||||
name:"effects"
|
||||
category:"sfx"
|
||||
PlayVariation {
|
||||
sample:"lava"
|
||||
maxGain:1.5
|
||||
minGain:1.2
|
||||
maxPitch:2.0
|
||||
minPitch:0.5
|
||||
}
|
||||
PlayVariation {
|
||||
sample:"explosion"
|
||||
maxGain:1.1
|
||||
minGain:0.7
|
||||
maxPitch:1.5
|
||||
minPitch:0.5
|
||||
}
|
||||
PlayVariation {
|
||||
sample:"water"
|
||||
maxGain:1.5
|
||||
minGain:1.2
|
||||
}
|
||||
}
|
||||
|
||||
dopplerFactor: 1
|
||||
speedOfSound: 343.33
|
||||
|
||||
listener.up:"0,0,1"
|
||||
listener.position:"0,0,0"
|
||||
listener.velocity:"0,0,0"
|
||||
listener.direction:"0,1,0"
|
||||
}
|
||||
405
examples/multimedia/audioinput/audioinput.cpp
Normal file
405
examples/multimedia/audioinput/audioinput.cpp
Normal file
@@ -0,0 +1,405 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QPainter>
|
||||
#include <QVBoxLayout>
|
||||
#include <QAudioDeviceInfo>
|
||||
#include <QAudioInput>
|
||||
#include <qendian.h>
|
||||
|
||||
#include "audioinput.h"
|
||||
|
||||
#define PUSH_MODE_LABEL "Enable push mode"
|
||||
#define PULL_MODE_LABEL "Enable pull mode"
|
||||
#define SUSPEND_LABEL "Suspend recording"
|
||||
#define RESUME_LABEL "Resume recording"
|
||||
|
||||
const int BufferSize = 4096;
|
||||
|
||||
AudioInfo::AudioInfo(const QAudioFormat &format, QObject *parent)
|
||||
: QIODevice(parent)
|
||||
, m_format(format)
|
||||
, m_maxAmplitude(0)
|
||||
, m_level(0.0)
|
||||
|
||||
{
|
||||
switch (m_format.sampleSize()) {
|
||||
case 8:
|
||||
switch (m_format.sampleType()) {
|
||||
case QAudioFormat::UnSignedInt:
|
||||
m_maxAmplitude = 255;
|
||||
break;
|
||||
case QAudioFormat::SignedInt:
|
||||
m_maxAmplitude = 127;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
switch (m_format.sampleType()) {
|
||||
case QAudioFormat::UnSignedInt:
|
||||
m_maxAmplitude = 65535;
|
||||
break;
|
||||
case QAudioFormat::SignedInt:
|
||||
m_maxAmplitude = 32767;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 32:
|
||||
switch (m_format.sampleType()) {
|
||||
case QAudioFormat::UnSignedInt:
|
||||
m_maxAmplitude = 0xffffffff;
|
||||
break;
|
||||
case QAudioFormat::SignedInt:
|
||||
m_maxAmplitude = 0x7fffffff;
|
||||
break;
|
||||
case QAudioFormat::Float:
|
||||
m_maxAmplitude = 0x7fffffff; // Kind of
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
AudioInfo::~AudioInfo()
|
||||
{
|
||||
}
|
||||
|
||||
void AudioInfo::start()
|
||||
{
|
||||
open(QIODevice::WriteOnly);
|
||||
}
|
||||
|
||||
void AudioInfo::stop()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
qint64 AudioInfo::readData(char *data, qint64 maxlen)
|
||||
{
|
||||
Q_UNUSED(data)
|
||||
Q_UNUSED(maxlen)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
qint64 AudioInfo::writeData(const char *data, qint64 len)
|
||||
{
|
||||
if (m_maxAmplitude) {
|
||||
Q_ASSERT(m_format.sampleSize() % 8 == 0);
|
||||
const int channelBytes = m_format.sampleSize() / 8;
|
||||
const int sampleBytes = m_format.channelCount() * channelBytes;
|
||||
Q_ASSERT(len % sampleBytes == 0);
|
||||
const int numSamples = len / sampleBytes;
|
||||
|
||||
quint32 maxValue = 0;
|
||||
const unsigned char *ptr = reinterpret_cast<const unsigned char *>(data);
|
||||
|
||||
for (int i = 0; i < numSamples; ++i) {
|
||||
for (int j = 0; j < m_format.channelCount(); ++j) {
|
||||
quint32 value = 0;
|
||||
|
||||
if (m_format.sampleSize() == 8 && m_format.sampleType() == QAudioFormat::UnSignedInt) {
|
||||
value = *reinterpret_cast<const quint8*>(ptr);
|
||||
} else if (m_format.sampleSize() == 8 && m_format.sampleType() == QAudioFormat::SignedInt) {
|
||||
value = qAbs(*reinterpret_cast<const qint8*>(ptr));
|
||||
} else if (m_format.sampleSize() == 16 && m_format.sampleType() == QAudioFormat::UnSignedInt) {
|
||||
if (m_format.byteOrder() == QAudioFormat::LittleEndian)
|
||||
value = qFromLittleEndian<quint16>(ptr);
|
||||
else
|
||||
value = qFromBigEndian<quint16>(ptr);
|
||||
} else if (m_format.sampleSize() == 16 && m_format.sampleType() == QAudioFormat::SignedInt) {
|
||||
if (m_format.byteOrder() == QAudioFormat::LittleEndian)
|
||||
value = qAbs(qFromLittleEndian<qint16>(ptr));
|
||||
else
|
||||
value = qAbs(qFromBigEndian<qint16>(ptr));
|
||||
} else if (m_format.sampleSize() == 32 && m_format.sampleType() == QAudioFormat::UnSignedInt) {
|
||||
if (m_format.byteOrder() == QAudioFormat::LittleEndian)
|
||||
value = qFromLittleEndian<quint32>(ptr);
|
||||
else
|
||||
value = qFromBigEndian<quint32>(ptr);
|
||||
} else if (m_format.sampleSize() == 32 && m_format.sampleType() == QAudioFormat::SignedInt) {
|
||||
if (m_format.byteOrder() == QAudioFormat::LittleEndian)
|
||||
value = qAbs(qFromLittleEndian<qint32>(ptr));
|
||||
else
|
||||
value = qAbs(qFromBigEndian<qint32>(ptr));
|
||||
} else if (m_format.sampleSize() == 32 && m_format.sampleType() == QAudioFormat::Float) {
|
||||
value = qAbs(*reinterpret_cast<const float*>(ptr) * 0x7fffffff); // assumes 0-1.0
|
||||
}
|
||||
|
||||
maxValue = qMax(value, maxValue);
|
||||
ptr += channelBytes;
|
||||
}
|
||||
}
|
||||
|
||||
maxValue = qMin(maxValue, m_maxAmplitude);
|
||||
m_level = qreal(maxValue) / m_maxAmplitude;
|
||||
}
|
||||
|
||||
emit update();
|
||||
return len;
|
||||
}
|
||||
|
||||
RenderArea::RenderArea(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
setBackgroundRole(QPalette::Base);
|
||||
setAutoFillBackground(true);
|
||||
|
||||
m_level = 0;
|
||||
setMinimumHeight(30);
|
||||
setMinimumWidth(200);
|
||||
}
|
||||
|
||||
void RenderArea::paintEvent(QPaintEvent * /* event */)
|
||||
{
|
||||
QPainter painter(this);
|
||||
|
||||
painter.setPen(Qt::black);
|
||||
painter.drawRect(QRect(painter.viewport().left()+10,
|
||||
painter.viewport().top()+10,
|
||||
painter.viewport().right()-20,
|
||||
painter.viewport().bottom()-20));
|
||||
if (m_level == 0.0)
|
||||
return;
|
||||
|
||||
int pos = ((painter.viewport().right()-20)-(painter.viewport().left()+11))*m_level;
|
||||
painter.fillRect(painter.viewport().left()+11,
|
||||
painter.viewport().top()+10,
|
||||
pos,
|
||||
painter.viewport().height()-21,
|
||||
Qt::red);
|
||||
}
|
||||
|
||||
void RenderArea::setLevel(qreal value)
|
||||
{
|
||||
m_level = value;
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
InputTest::InputTest()
|
||||
: m_canvas(0)
|
||||
, m_modeButton(0)
|
||||
, m_suspendResumeButton(0)
|
||||
, m_deviceBox(0)
|
||||
, m_device(QAudioDeviceInfo::defaultInputDevice())
|
||||
, m_audioInfo(0)
|
||||
, m_audioInput(0)
|
||||
, m_input(0)
|
||||
, m_pullMode(false)
|
||||
, m_buffer(BufferSize, 0)
|
||||
{
|
||||
initializeWindow();
|
||||
initializeAudio();
|
||||
}
|
||||
|
||||
InputTest::~InputTest() {}
|
||||
|
||||
void InputTest::initializeWindow()
|
||||
{
|
||||
QScopedPointer<QWidget> window(new QWidget);
|
||||
QScopedPointer<QVBoxLayout> layout(new QVBoxLayout);
|
||||
|
||||
m_canvas = new RenderArea(this);
|
||||
layout->addWidget(m_canvas);
|
||||
|
||||
m_deviceBox = new QComboBox(this);
|
||||
QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
|
||||
for(int i = 0; i < devices.size(); ++i)
|
||||
m_deviceBox->addItem(devices.at(i).deviceName(), qVariantFromValue(devices.at(i)));
|
||||
|
||||
connect(m_deviceBox, SIGNAL(activated(int)), SLOT(deviceChanged(int)));
|
||||
layout->addWidget(m_deviceBox);
|
||||
|
||||
m_volumeSlider = new QSlider(Qt::Horizontal, this);
|
||||
m_volumeSlider->setRange(0, 100);
|
||||
m_volumeSlider->setValue(100);
|
||||
connect(m_volumeSlider, SIGNAL(valueChanged(int)), SLOT(sliderChanged(int)));
|
||||
layout->addWidget(m_volumeSlider);
|
||||
|
||||
m_modeButton = new QPushButton(this);
|
||||
m_modeButton->setText(tr(PUSH_MODE_LABEL));
|
||||
connect(m_modeButton, SIGNAL(clicked()), SLOT(toggleMode()));
|
||||
layout->addWidget(m_modeButton);
|
||||
|
||||
m_suspendResumeButton = new QPushButton(this);
|
||||
m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
|
||||
connect(m_suspendResumeButton, SIGNAL(clicked()), SLOT(toggleSuspend()));
|
||||
layout->addWidget(m_suspendResumeButton);
|
||||
|
||||
window->setLayout(layout.data());
|
||||
layout.take(); // ownership transferred
|
||||
|
||||
setCentralWidget(window.data());
|
||||
QWidget *const windowPtr = window.take(); // ownership transferred
|
||||
windowPtr->show();
|
||||
}
|
||||
|
||||
void InputTest::initializeAudio()
|
||||
{
|
||||
m_pullMode = true;
|
||||
|
||||
m_format.setSampleRate(8000);
|
||||
m_format.setChannelCount(1);
|
||||
m_format.setSampleSize(16);
|
||||
m_format.setSampleType(QAudioFormat::SignedInt);
|
||||
m_format.setByteOrder(QAudioFormat::LittleEndian);
|
||||
m_format.setCodec("audio/pcm");
|
||||
|
||||
QAudioDeviceInfo info(QAudioDeviceInfo::defaultInputDevice());
|
||||
if (!info.isFormatSupported(m_format)) {
|
||||
qWarning() << "Default format not supported - trying to use nearest";
|
||||
m_format = info.nearestFormat(m_format);
|
||||
}
|
||||
|
||||
m_audioInfo = new AudioInfo(m_format, this);
|
||||
connect(m_audioInfo, SIGNAL(update()), SLOT(refreshDisplay()));
|
||||
|
||||
createAudioInput();
|
||||
}
|
||||
|
||||
void InputTest::createAudioInput()
|
||||
{
|
||||
m_audioInput = new QAudioInput(m_device, m_format, this);
|
||||
connect(m_audioInput, SIGNAL(notify()), SLOT(notified()));
|
||||
connect(m_audioInput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State)));
|
||||
m_volumeSlider->setValue(m_audioInput->volume() * 100);
|
||||
m_audioInfo->start();
|
||||
m_audioInput->start(m_audioInfo);
|
||||
}
|
||||
|
||||
void InputTest::notified()
|
||||
{
|
||||
qWarning() << "bytesReady = " << m_audioInput->bytesReady()
|
||||
<< ", " << "elapsedUSecs = " <<m_audioInput->elapsedUSecs()
|
||||
<< ", " << "processedUSecs = "<<m_audioInput->processedUSecs();
|
||||
}
|
||||
|
||||
void InputTest::readMore()
|
||||
{
|
||||
if (!m_audioInput)
|
||||
return;
|
||||
qint64 len = m_audioInput->bytesReady();
|
||||
if (len > BufferSize)
|
||||
len = BufferSize;
|
||||
qint64 l = m_input->read(m_buffer.data(), len);
|
||||
if (l > 0)
|
||||
m_audioInfo->write(m_buffer.constData(), l);
|
||||
}
|
||||
|
||||
void InputTest::toggleMode()
|
||||
{
|
||||
// Change bewteen pull and push modes
|
||||
m_audioInput->stop();
|
||||
|
||||
if (m_pullMode) {
|
||||
m_modeButton->setText(tr(PULL_MODE_LABEL));
|
||||
m_input = m_audioInput->start();
|
||||
connect(m_input, SIGNAL(readyRead()), SLOT(readMore()));
|
||||
m_pullMode = false;
|
||||
} else {
|
||||
m_modeButton->setText(tr(PUSH_MODE_LABEL));
|
||||
m_pullMode = true;
|
||||
m_audioInput->start(m_audioInfo);
|
||||
}
|
||||
|
||||
m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
|
||||
}
|
||||
|
||||
void InputTest::toggleSuspend()
|
||||
{
|
||||
// toggle suspend/resume
|
||||
if (m_audioInput->state() == QAudio::SuspendedState) {
|
||||
qWarning() << "status: Suspended, resume()";
|
||||
m_audioInput->resume();
|
||||
m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
|
||||
} else if (m_audioInput->state() == QAudio::ActiveState) {
|
||||
qWarning() << "status: Active, suspend()";
|
||||
m_audioInput->suspend();
|
||||
m_suspendResumeButton->setText(tr(RESUME_LABEL));
|
||||
} else if (m_audioInput->state() == QAudio::StoppedState) {
|
||||
qWarning() << "status: Stopped, resume()";
|
||||
m_audioInput->resume();
|
||||
m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
|
||||
} else if (m_audioInput->state() == QAudio::IdleState) {
|
||||
qWarning() << "status: IdleState";
|
||||
}
|
||||
}
|
||||
|
||||
void InputTest::stateChanged(QAudio::State state)
|
||||
{
|
||||
qWarning() << "state = " << state;
|
||||
}
|
||||
|
||||
void InputTest::refreshDisplay()
|
||||
{
|
||||
m_canvas->setLevel(m_audioInfo->level());
|
||||
}
|
||||
|
||||
void InputTest::deviceChanged(int index)
|
||||
{
|
||||
m_audioInfo->stop();
|
||||
m_audioInput->stop();
|
||||
m_audioInput->disconnect(this);
|
||||
delete m_audioInput;
|
||||
|
||||
m_device = m_deviceBox->itemData(index).value<QAudioDeviceInfo>();
|
||||
createAudioInput();
|
||||
}
|
||||
|
||||
void InputTest::sliderChanged(int value)
|
||||
{
|
||||
if (m_audioInput)
|
||||
m_audioInput->setVolume(qreal(value) / 100);
|
||||
}
|
||||
138
examples/multimedia/audioinput/audioinput.h
Normal file
138
examples/multimedia/audioinput/audioinput.h
Normal file
@@ -0,0 +1,138 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef AUDIOINPUT_H
|
||||
#define AUDIOINPUT_H
|
||||
|
||||
#include <QAudioInput>
|
||||
#include <QByteArray>
|
||||
#include <QComboBox>
|
||||
#include <QMainWindow>
|
||||
#include <QObject>
|
||||
#include <QPixmap>
|
||||
#include <QPushButton>
|
||||
#include <QSlider>
|
||||
#include <QWidget>
|
||||
|
||||
class AudioInfo : public QIODevice
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AudioInfo(const QAudioFormat &format, QObject *parent);
|
||||
~AudioInfo();
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
qreal level() const { return m_level; }
|
||||
|
||||
qint64 readData(char *data, qint64 maxlen);
|
||||
qint64 writeData(const char *data, qint64 len);
|
||||
|
||||
private:
|
||||
const QAudioFormat m_format;
|
||||
quint32 m_maxAmplitude;
|
||||
qreal m_level; // 0.0 <= m_level <= 1.0
|
||||
|
||||
signals:
|
||||
void update();
|
||||
};
|
||||
|
||||
|
||||
class RenderArea : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RenderArea(QWidget *parent = 0);
|
||||
|
||||
void setLevel(qreal value);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event);
|
||||
|
||||
private:
|
||||
qreal m_level;
|
||||
QPixmap m_pixmap;
|
||||
};
|
||||
|
||||
|
||||
class InputTest : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
InputTest();
|
||||
~InputTest();
|
||||
|
||||
private:
|
||||
void initializeWindow();
|
||||
void initializeAudio();
|
||||
void createAudioInput();
|
||||
|
||||
private slots:
|
||||
void refreshDisplay();
|
||||
void notified();
|
||||
void readMore();
|
||||
void toggleMode();
|
||||
void toggleSuspend();
|
||||
void stateChanged(QAudio::State state);
|
||||
void deviceChanged(int index);
|
||||
void sliderChanged(int value);
|
||||
|
||||
private:
|
||||
// Owned by layout
|
||||
RenderArea *m_canvas;
|
||||
QPushButton *m_modeButton;
|
||||
QPushButton *m_suspendResumeButton;
|
||||
QComboBox *m_deviceBox;
|
||||
QSlider *m_volumeSlider;
|
||||
|
||||
QAudioDeviceInfo m_device;
|
||||
AudioInfo *m_audioInfo;
|
||||
QAudioFormat m_format;
|
||||
QAudioInput *m_audioInput;
|
||||
QIODevice *m_input;
|
||||
bool m_pullMode;
|
||||
QByteArray m_buffer;
|
||||
};
|
||||
|
||||
#endif // AUDIOINPUT_H
|
||||
12
examples/multimedia/audioinput/audioinput.pro
Normal file
12
examples/multimedia/audioinput/audioinput.pro
Normal file
@@ -0,0 +1,12 @@
|
||||
TEMPLATE = app
|
||||
TARGET = audioinput
|
||||
|
||||
QT += multimedia widgets
|
||||
|
||||
HEADERS = audioinput.h
|
||||
|
||||
SOURCES = audioinput.cpp \
|
||||
main.cpp
|
||||
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/audioinput
|
||||
INSTALLS += target
|
||||
BIN
examples/multimedia/audioinput/doc/images/audioinput-example.png
Normal file
BIN
examples/multimedia/audioinput/doc/images/audioinput-example.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
43
examples/multimedia/audioinput/doc/src/audioinput.qdoc
Normal file
43
examples/multimedia/audioinput/doc/src/audioinput.qdoc
Normal file
@@ -0,0 +1,43 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:FDL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Free Documentation License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Free
|
||||
** Documentation License version 1.3 as published by the Free Software
|
||||
** Foundation and appearing in the file included in the packaging of
|
||||
** this file. Please review the following information to ensure
|
||||
** the GNU Free Documentation License version 1.3 requirements
|
||||
** will be met: http://www.gnu.org/copyleft/fdl.html.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\example audioinput
|
||||
\title Audio Input Example
|
||||
\ingroup audio_examples
|
||||
\brief The Audio Input Example shows the use of the QAudioInput class.
|
||||
The example demonstrates the basic use cases of the QAudioInput class.
|
||||
|
||||
\image audioinput-example.png
|
||||
|
||||
Qt provides the QAudioInput class to enable audio functionality within
|
||||
a standard application user interface.
|
||||
|
||||
This example calculates the maximum linear value of the input audio from the microphone and displays the output.
|
||||
*/
|
||||
|
||||
|
||||
54
examples/multimedia/audioinput/main.cpp
Normal file
54
examples/multimedia/audioinput/main.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "audioinput.h"
|
||||
|
||||
int main(int argv, char **args)
|
||||
{
|
||||
QApplication app(argv, args);
|
||||
app.setApplicationName("Audio Input Test");
|
||||
|
||||
InputTest input;
|
||||
input.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
334
examples/multimedia/audiooutput/audiooutput.cpp
Normal file
334
examples/multimedia/audiooutput/audiooutput.cpp
Normal file
@@ -0,0 +1,334 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QAudioDeviceInfo>
|
||||
#include <QAudioOutput>
|
||||
#include <QDebug>
|
||||
#include <QVBoxLayout>
|
||||
#include <qmath.h>
|
||||
#include <qendian.h>
|
||||
|
||||
#include "audiooutput.h"
|
||||
|
||||
#define PUSH_MODE_LABEL "Enable push mode"
|
||||
#define PULL_MODE_LABEL "Enable pull mode"
|
||||
#define SUSPEND_LABEL "Suspend playback"
|
||||
#define RESUME_LABEL "Resume playback"
|
||||
#define VOLUME_LABEL "Volume:"
|
||||
|
||||
const int DurationSeconds = 1;
|
||||
const int ToneSampleRateHz = 600;
|
||||
const int DataSampleRateHz = 44100;
|
||||
const int BufferSize = 32768;
|
||||
|
||||
|
||||
Generator::Generator(const QAudioFormat &format,
|
||||
qint64 durationUs,
|
||||
int sampleRate,
|
||||
QObject *parent)
|
||||
: QIODevice(parent)
|
||||
, m_pos(0)
|
||||
{
|
||||
generateData(format, durationUs, sampleRate);
|
||||
}
|
||||
|
||||
Generator::~Generator()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Generator::start()
|
||||
{
|
||||
open(QIODevice::ReadOnly);
|
||||
}
|
||||
|
||||
void Generator::stop()
|
||||
{
|
||||
m_pos = 0;
|
||||
close();
|
||||
}
|
||||
|
||||
void Generator::generateData(const QAudioFormat &format, qint64 durationUs, int sampleRate)
|
||||
{
|
||||
const int channelBytes = format.sampleSize() / 8;
|
||||
const int sampleBytes = format.channelCount() * channelBytes;
|
||||
|
||||
qint64 length = (format.sampleRate() * format.channelCount() * (format.sampleSize() / 8))
|
||||
* durationUs / 100000;
|
||||
|
||||
Q_ASSERT(length % sampleBytes == 0);
|
||||
Q_UNUSED(sampleBytes) // suppress warning in release builds
|
||||
|
||||
m_buffer.resize(length);
|
||||
unsigned char *ptr = reinterpret_cast<unsigned char *>(m_buffer.data());
|
||||
int sampleIndex = 0;
|
||||
|
||||
while (length) {
|
||||
const qreal x = qSin(2 * M_PI * sampleRate * qreal(sampleIndex % format.sampleRate()) / format.sampleRate());
|
||||
for (int i=0; i<format.channelCount(); ++i) {
|
||||
if (format.sampleSize() == 8 && format.sampleType() == QAudioFormat::UnSignedInt) {
|
||||
const quint8 value = static_cast<quint8>((1.0 + x) / 2 * 255);
|
||||
*reinterpret_cast<quint8*>(ptr) = value;
|
||||
} else if (format.sampleSize() == 8 && format.sampleType() == QAudioFormat::SignedInt) {
|
||||
const qint8 value = static_cast<qint8>(x * 127);
|
||||
*reinterpret_cast<quint8*>(ptr) = value;
|
||||
} else if (format.sampleSize() == 16 && format.sampleType() == QAudioFormat::UnSignedInt) {
|
||||
quint16 value = static_cast<quint16>((1.0 + x) / 2 * 65535);
|
||||
if (format.byteOrder() == QAudioFormat::LittleEndian)
|
||||
qToLittleEndian<quint16>(value, ptr);
|
||||
else
|
||||
qToBigEndian<quint16>(value, ptr);
|
||||
} else if (format.sampleSize() == 16 && format.sampleType() == QAudioFormat::SignedInt) {
|
||||
qint16 value = static_cast<qint16>(x * 32767);
|
||||
if (format.byteOrder() == QAudioFormat::LittleEndian)
|
||||
qToLittleEndian<qint16>(value, ptr);
|
||||
else
|
||||
qToBigEndian<qint16>(value, ptr);
|
||||
}
|
||||
|
||||
ptr += channelBytes;
|
||||
length -= channelBytes;
|
||||
}
|
||||
++sampleIndex;
|
||||
}
|
||||
}
|
||||
|
||||
qint64 Generator::readData(char *data, qint64 len)
|
||||
{
|
||||
qint64 total = 0;
|
||||
while (len - total > 0) {
|
||||
const qint64 chunk = qMin((m_buffer.size() - m_pos), len - total);
|
||||
memcpy(data + total, m_buffer.constData() + m_pos, chunk);
|
||||
m_pos = (m_pos + chunk) % m_buffer.size();
|
||||
total += chunk;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
qint64 Generator::writeData(const char *data, qint64 len)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
Q_UNUSED(len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
qint64 Generator::bytesAvailable() const
|
||||
{
|
||||
return m_buffer.size() + QIODevice::bytesAvailable();
|
||||
}
|
||||
|
||||
AudioTest::AudioTest()
|
||||
: m_pullTimer(new QTimer(this))
|
||||
, m_modeButton(0)
|
||||
, m_suspendResumeButton(0)
|
||||
, m_deviceBox(0)
|
||||
, m_device(QAudioDeviceInfo::defaultOutputDevice())
|
||||
, m_generator(0)
|
||||
, m_audioOutput(0)
|
||||
, m_output(0)
|
||||
, m_buffer(BufferSize, 0)
|
||||
{
|
||||
initializeWindow();
|
||||
initializeAudio();
|
||||
}
|
||||
|
||||
void AudioTest::initializeWindow()
|
||||
{
|
||||
QScopedPointer<QWidget> window(new QWidget);
|
||||
QScopedPointer<QVBoxLayout> layout(new QVBoxLayout);
|
||||
|
||||
m_deviceBox = new QComboBox(this);
|
||||
foreach (const QAudioDeviceInfo &deviceInfo, QAudioDeviceInfo::availableDevices(QAudio::AudioOutput))
|
||||
m_deviceBox->addItem(deviceInfo.deviceName(), qVariantFromValue(deviceInfo));
|
||||
connect(m_deviceBox,SIGNAL(activated(int)),SLOT(deviceChanged(int)));
|
||||
layout->addWidget(m_deviceBox);
|
||||
|
||||
m_modeButton = new QPushButton(this);
|
||||
m_modeButton->setText(tr(PUSH_MODE_LABEL));
|
||||
connect(m_modeButton, SIGNAL(clicked()), SLOT(toggleMode()));
|
||||
layout->addWidget(m_modeButton);
|
||||
|
||||
m_suspendResumeButton = new QPushButton(this);
|
||||
m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
|
||||
connect(m_suspendResumeButton, SIGNAL(clicked()), SLOT(toggleSuspendResume()));
|
||||
layout->addWidget(m_suspendResumeButton);
|
||||
|
||||
QHBoxLayout *volumeBox = new QHBoxLayout;
|
||||
m_volumeLabel = new QLabel;
|
||||
m_volumeLabel->setText(tr(VOLUME_LABEL));
|
||||
m_volumeSlider = new QSlider(Qt::Horizontal);
|
||||
m_volumeSlider->setMinimum(0);
|
||||
m_volumeSlider->setMaximum(100);
|
||||
m_volumeSlider->setSingleStep(10);
|
||||
connect(m_volumeSlider, SIGNAL(valueChanged(int)), this, SLOT(volumeChanged(int)));
|
||||
volumeBox->addWidget(m_volumeLabel);
|
||||
volumeBox->addWidget(m_volumeSlider);
|
||||
layout->addLayout(volumeBox);
|
||||
|
||||
window->setLayout(layout.data());
|
||||
layout.take(); // ownership transferred
|
||||
|
||||
setCentralWidget(window.data());
|
||||
QWidget *const windowPtr = window.take(); // ownership transferred
|
||||
windowPtr->show();
|
||||
}
|
||||
|
||||
void AudioTest::initializeAudio()
|
||||
{
|
||||
connect(m_pullTimer, SIGNAL(timeout()), SLOT(pullTimerExpired()));
|
||||
|
||||
m_pullMode = true;
|
||||
|
||||
m_format.setSampleRate(DataSampleRateHz);
|
||||
m_format.setChannelCount(1);
|
||||
m_format.setSampleSize(16);
|
||||
m_format.setCodec("audio/pcm");
|
||||
m_format.setByteOrder(QAudioFormat::LittleEndian);
|
||||
m_format.setSampleType(QAudioFormat::SignedInt);
|
||||
|
||||
QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
|
||||
if (!info.isFormatSupported(m_format)) {
|
||||
qWarning() << "Default format not supported - trying to use nearest";
|
||||
m_format = info.nearestFormat(m_format);
|
||||
}
|
||||
|
||||
m_generator = new Generator(m_format, DurationSeconds*1000000, ToneSampleRateHz, this);
|
||||
|
||||
createAudioOutput();
|
||||
}
|
||||
|
||||
void AudioTest::createAudioOutput()
|
||||
{
|
||||
delete m_audioOutput;
|
||||
m_audioOutput = 0;
|
||||
m_audioOutput = new QAudioOutput(m_device, m_format, this);
|
||||
connect(m_audioOutput, SIGNAL(notify()), SLOT(notified()));
|
||||
connect(m_audioOutput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State)));
|
||||
m_generator->start();
|
||||
m_audioOutput->start(m_generator);
|
||||
m_volumeSlider->setValue(int(m_audioOutput->volume()*100.0f));
|
||||
}
|
||||
|
||||
AudioTest::~AudioTest()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AudioTest::deviceChanged(int index)
|
||||
{
|
||||
m_pullTimer->stop();
|
||||
m_generator->stop();
|
||||
m_audioOutput->stop();
|
||||
m_audioOutput->disconnect(this);
|
||||
m_device = m_deviceBox->itemData(index).value<QAudioDeviceInfo>();
|
||||
createAudioOutput();
|
||||
}
|
||||
|
||||
void AudioTest::volumeChanged(int value)
|
||||
{
|
||||
if (m_audioOutput)
|
||||
m_audioOutput->setVolume(qreal(value/100.0f));
|
||||
}
|
||||
|
||||
void AudioTest::notified()
|
||||
{
|
||||
qWarning() << "bytesFree = " << m_audioOutput->bytesFree()
|
||||
<< ", " << "elapsedUSecs = " << m_audioOutput->elapsedUSecs()
|
||||
<< ", " << "processedUSecs = " << m_audioOutput->processedUSecs();
|
||||
}
|
||||
|
||||
void AudioTest::pullTimerExpired()
|
||||
{
|
||||
if (m_audioOutput && m_audioOutput->state() != QAudio::StoppedState) {
|
||||
int chunks = m_audioOutput->bytesFree()/m_audioOutput->periodSize();
|
||||
while (chunks) {
|
||||
const qint64 len = m_generator->read(m_buffer.data(), m_audioOutput->periodSize());
|
||||
if (len)
|
||||
m_output->write(m_buffer.data(), len);
|
||||
if (len != m_audioOutput->periodSize())
|
||||
break;
|
||||
--chunks;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AudioTest::toggleMode()
|
||||
{
|
||||
m_pullTimer->stop();
|
||||
m_audioOutput->stop();
|
||||
|
||||
if (m_pullMode) {
|
||||
m_modeButton->setText(tr(PULL_MODE_LABEL));
|
||||
m_output = m_audioOutput->start();
|
||||
m_pullMode = false;
|
||||
m_pullTimer->start(20);
|
||||
} else {
|
||||
m_modeButton->setText(tr(PUSH_MODE_LABEL));
|
||||
m_pullMode = true;
|
||||
m_audioOutput->start(m_generator);
|
||||
}
|
||||
|
||||
m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
|
||||
}
|
||||
|
||||
void AudioTest::toggleSuspendResume()
|
||||
{
|
||||
if (m_audioOutput->state() == QAudio::SuspendedState) {
|
||||
qWarning() << "status: Suspended, resume()";
|
||||
m_audioOutput->resume();
|
||||
m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
|
||||
} else if (m_audioOutput->state() == QAudio::ActiveState) {
|
||||
qWarning() << "status: Active, suspend()";
|
||||
m_audioOutput->suspend();
|
||||
m_suspendResumeButton->setText(tr(RESUME_LABEL));
|
||||
} else if (m_audioOutput->state() == QAudio::StoppedState) {
|
||||
qWarning() << "status: Stopped, resume()";
|
||||
m_audioOutput->resume();
|
||||
m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
|
||||
} else if (m_audioOutput->state() == QAudio::IdleState) {
|
||||
qWarning() << "status: IdleState";
|
||||
}
|
||||
}
|
||||
|
||||
void AudioTest::stateChanged(QAudio::State state)
|
||||
{
|
||||
qWarning() << "state = " << state;
|
||||
}
|
||||
122
examples/multimedia/audiooutput/audiooutput.h
Normal file
122
examples/multimedia/audiooutput/audiooutput.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef AUDIOOUTPUT_H
|
||||
#define AUDIOOUTPUT_H
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <QAudioOutput>
|
||||
#include <QByteArray>
|
||||
#include <QComboBox>
|
||||
#include <QIODevice>
|
||||
#include <QLabel>
|
||||
#include <QMainWindow>
|
||||
#include <QObject>
|
||||
#include <QPushButton>
|
||||
#include <QSlider>
|
||||
#include <QTimer>
|
||||
|
||||
class Generator : public QIODevice
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Generator(const QAudioFormat &format, qint64 durationUs, int sampleRate, QObject *parent);
|
||||
~Generator();
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
qint64 readData(char *data, qint64 maxlen);
|
||||
qint64 writeData(const char *data, qint64 len);
|
||||
qint64 bytesAvailable() const;
|
||||
|
||||
private:
|
||||
void generateData(const QAudioFormat &format, qint64 durationUs, int sampleRate);
|
||||
|
||||
private:
|
||||
qint64 m_pos;
|
||||
QByteArray m_buffer;
|
||||
};
|
||||
|
||||
class AudioTest : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AudioTest();
|
||||
~AudioTest();
|
||||
|
||||
private:
|
||||
void initializeWindow();
|
||||
void initializeAudio();
|
||||
void createAudioOutput();
|
||||
|
||||
private:
|
||||
QTimer *m_pullTimer;
|
||||
|
||||
// Owned by layout
|
||||
QPushButton *m_modeButton;
|
||||
QPushButton *m_suspendResumeButton;
|
||||
QComboBox *m_deviceBox;
|
||||
QLabel *m_volumeLabel;
|
||||
QSlider *m_volumeSlider;
|
||||
|
||||
QAudioDeviceInfo m_device;
|
||||
Generator *m_generator;
|
||||
QAudioOutput *m_audioOutput;
|
||||
QIODevice *m_output; // not owned
|
||||
QAudioFormat m_format;
|
||||
|
||||
bool m_pullMode;
|
||||
QByteArray m_buffer;
|
||||
|
||||
private slots:
|
||||
void notified();
|
||||
void pullTimerExpired();
|
||||
void toggleMode();
|
||||
void toggleSuspendResume();
|
||||
void stateChanged(QAudio::State state);
|
||||
void deviceChanged(int index);
|
||||
void volumeChanged(int);
|
||||
};
|
||||
|
||||
#endif // AUDIOOUTPUT_H
|
||||
12
examples/multimedia/audiooutput/audiooutput.pro
Normal file
12
examples/multimedia/audiooutput/audiooutput.pro
Normal file
@@ -0,0 +1,12 @@
|
||||
TEMPLATE = app
|
||||
TARGET = audiooutput
|
||||
|
||||
QT += multimedia widgets
|
||||
|
||||
HEADERS = audiooutput.h
|
||||
|
||||
SOURCES = audiooutput.cpp \
|
||||
main.cpp
|
||||
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/audiooutput
|
||||
INSTALLS += target
|
||||
BIN
examples/multimedia/audiooutput/doc/images/audiooutput-example.png
Executable file
BIN
examples/multimedia/audiooutput/doc/images/audiooutput-example.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
43
examples/multimedia/audiooutput/doc/src/audiooutput.qdoc
Normal file
43
examples/multimedia/audiooutput/doc/src/audiooutput.qdoc
Normal file
@@ -0,0 +1,43 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:FDL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Free Documentation License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Free
|
||||
** Documentation License version 1.3 as published by the Free Software
|
||||
** Foundation and appearing in the file included in the packaging of
|
||||
** this file. Please review the following information to ensure
|
||||
** the GNU Free Documentation License version 1.3 requirements
|
||||
** will be met: http://www.gnu.org/copyleft/fdl.html.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\example audiooutput
|
||||
\title Audio Output Example
|
||||
\ingroup audio_examples
|
||||
\brief The Audio Output Example show the use of the QAudioOutput API.
|
||||
|
||||
The example demonstrates the basic use cases of the QAudioOutput class.
|
||||
|
||||
\image audiooutput-example.png
|
||||
|
||||
This example provides a tone generator to supply continuous audio playback.
|
||||
The first button allows pause and resume of the playback, and the second
|
||||
button allows toggling between push and pull modes of operation.
|
||||
*/
|
||||
|
||||
|
||||
54
examples/multimedia/audiooutput/main.cpp
Normal file
54
examples/multimedia/audiooutput/main.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
#include "audiooutput.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
app.setApplicationName("Audio Output Test");
|
||||
|
||||
AudioTest audio;
|
||||
audio.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
319
examples/multimedia/audiorecorder/audiorecorder.cpp
Normal file
319
examples/multimedia/audiorecorder/audiorecorder.cpp
Normal file
@@ -0,0 +1,319 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QAudioProbe>
|
||||
#include <QAudioRecorder>
|
||||
#include <QDir>
|
||||
#include <QFileDialog>
|
||||
#include <QMediaRecorder>
|
||||
|
||||
#include "audiorecorder.h"
|
||||
|
||||
#if defined(Q_WS_MAEMO_6)
|
||||
#include "ui_audiorecorder_small.h"
|
||||
#else
|
||||
#include "ui_audiorecorder.h"
|
||||
#endif
|
||||
|
||||
static qreal getPeakValue(const QAudioFormat &format);
|
||||
static qreal getBufferLevel(const QAudioBuffer &buffer);
|
||||
|
||||
template <class T>
|
||||
static qreal getBufferLevel(const T *buffer, int samples);
|
||||
|
||||
AudioRecorder::AudioRecorder(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::AudioRecorder),
|
||||
outputLocationSet(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
audioRecorder = new QAudioRecorder(this);
|
||||
probe = new QAudioProbe;
|
||||
connect(probe, SIGNAL(audioBufferProbed(QAudioBuffer)), this, SLOT(processBuffer(QAudioBuffer)));
|
||||
probe->setSource(audioRecorder);
|
||||
|
||||
//audio devices
|
||||
ui->audioDeviceBox->addItem(tr("Default"), QVariant(QString()));
|
||||
foreach (const QString &device, audioRecorder->audioInputs()) {
|
||||
ui->audioDeviceBox->addItem(device, QVariant(device));
|
||||
}
|
||||
|
||||
//audio codecs
|
||||
ui->audioCodecBox->addItem(tr("Default"), QVariant(QString()));
|
||||
foreach (const QString &codecName, audioRecorder->supportedAudioCodecs()) {
|
||||
ui->audioCodecBox->addItem(codecName, QVariant(codecName));
|
||||
}
|
||||
|
||||
//containers
|
||||
ui->containerBox->addItem(tr("Default"), QVariant(QString()));
|
||||
foreach (const QString &containerName, audioRecorder->supportedContainers()) {
|
||||
ui->containerBox->addItem(containerName, QVariant(containerName));
|
||||
}
|
||||
|
||||
//sample rate:
|
||||
ui->sampleRateBox->addItem(tr("Default"), QVariant(0));
|
||||
foreach (int sampleRate, audioRecorder->supportedAudioSampleRates()) {
|
||||
ui->sampleRateBox->addItem(QString::number(sampleRate), QVariant(
|
||||
sampleRate));
|
||||
}
|
||||
|
||||
ui->qualitySlider->setRange(0, int(QMultimedia::VeryHighQuality));
|
||||
ui->qualitySlider->setValue(int(QMultimedia::NormalQuality));
|
||||
|
||||
//bitrates:
|
||||
ui->bitrateBox->addItem(QString("Default"), QVariant(0));
|
||||
ui->bitrateBox->addItem(QString("32000"), QVariant(32000));
|
||||
ui->bitrateBox->addItem(QString("64000"), QVariant(64000));
|
||||
ui->bitrateBox->addItem(QString("96000"), QVariant(96000));
|
||||
ui->bitrateBox->addItem(QString("128000"), QVariant(128000));
|
||||
|
||||
connect(audioRecorder, SIGNAL(durationChanged(qint64)), this,
|
||||
SLOT(updateProgress(qint64)));
|
||||
connect(audioRecorder, SIGNAL(stateChanged(QMediaRecorder::State)), this,
|
||||
SLOT(updateState(QMediaRecorder::State)));
|
||||
connect(audioRecorder, SIGNAL(error(QMediaRecorder::Error)), this,
|
||||
SLOT(displayErrorMessage()));
|
||||
}
|
||||
|
||||
AudioRecorder::~AudioRecorder()
|
||||
{
|
||||
delete audioRecorder;
|
||||
delete probe;
|
||||
}
|
||||
|
||||
void AudioRecorder::updateProgress(qint64 duration)
|
||||
{
|
||||
if (audioRecorder->error() != QMediaRecorder::NoError || duration < 2000)
|
||||
return;
|
||||
|
||||
ui->statusbar->showMessage(tr("Recorded %1 sec").arg(duration / 1000));
|
||||
}
|
||||
|
||||
void AudioRecorder::updateState(QMediaRecorder::State state)
|
||||
{
|
||||
QString statusMessage;
|
||||
|
||||
switch (state) {
|
||||
case QMediaRecorder::RecordingState:
|
||||
ui->recordButton->setText(tr("Stop"));
|
||||
ui->pauseButton->setText(tr("Pause"));
|
||||
if (audioRecorder->outputLocation().isEmpty())
|
||||
statusMessage = tr("Recording");
|
||||
else
|
||||
statusMessage = tr("Recording to %1").arg(
|
||||
audioRecorder->outputLocation().toString());
|
||||
break;
|
||||
case QMediaRecorder::PausedState:
|
||||
ui->recordButton->setText(tr("Stop"));
|
||||
ui->pauseButton->setText(tr("Resume"));
|
||||
statusMessage = tr("Paused");
|
||||
break;
|
||||
case QMediaRecorder::StoppedState:
|
||||
ui->recordButton->setText(tr("Record"));
|
||||
ui->pauseButton->setText(tr("Pause"));
|
||||
statusMessage = tr("Stopped");
|
||||
}
|
||||
|
||||
ui->pauseButton->setEnabled(state != QMediaRecorder::StoppedState);
|
||||
|
||||
if (audioRecorder->error() == QMediaRecorder::NoError)
|
||||
ui->statusbar->showMessage(statusMessage);
|
||||
}
|
||||
|
||||
static QVariant boxValue(const QComboBox *box)
|
||||
{
|
||||
int idx = box->currentIndex();
|
||||
if (idx == -1)
|
||||
return QVariant();
|
||||
|
||||
return box->itemData(idx);
|
||||
}
|
||||
|
||||
void AudioRecorder::toggleRecord()
|
||||
{
|
||||
if (audioRecorder->state() == QMediaRecorder::StoppedState) {
|
||||
audioRecorder->setAudioInput(boxValue(ui->audioDeviceBox).toString());
|
||||
|
||||
if (!outputLocationSet)
|
||||
audioRecorder->setOutputLocation(generateAudioFilePath());
|
||||
|
||||
QAudioEncoderSettings settings;
|
||||
settings.setCodec(boxValue(ui->audioCodecBox).toString());
|
||||
settings.setSampleRate(boxValue(ui->sampleRateBox).toInt());
|
||||
settings.setBitRate(boxValue(ui->bitrateBox).toInt());
|
||||
settings.setQuality(QMultimedia::EncodingQuality(ui->qualitySlider->value()));
|
||||
settings.setEncodingMode(ui->constantQualityRadioButton->isChecked() ?
|
||||
QMultimedia::ConstantQualityEncoding :
|
||||
QMultimedia::ConstantBitRateEncoding);
|
||||
|
||||
QString container = boxValue(ui->containerBox).toString();
|
||||
|
||||
audioRecorder->setEncodingSettings(settings, QVideoEncoderSettings(), container);
|
||||
audioRecorder->record();
|
||||
}
|
||||
else {
|
||||
audioRecorder->stop();
|
||||
}
|
||||
}
|
||||
|
||||
void AudioRecorder::togglePause()
|
||||
{
|
||||
if (audioRecorder->state() != QMediaRecorder::PausedState)
|
||||
audioRecorder->pause();
|
||||
else
|
||||
audioRecorder->record();
|
||||
}
|
||||
|
||||
void AudioRecorder::setOutputLocation()
|
||||
{
|
||||
QString fileName = QFileDialog::getSaveFileName();
|
||||
audioRecorder->setOutputLocation(QUrl(fileName));
|
||||
outputLocationSet = true;
|
||||
}
|
||||
|
||||
void AudioRecorder::displayErrorMessage()
|
||||
{
|
||||
ui->statusbar->showMessage(audioRecorder->errorString());
|
||||
}
|
||||
|
||||
QUrl AudioRecorder::generateAudioFilePath()
|
||||
{
|
||||
QDir outputDir(QDir::rootPath());
|
||||
|
||||
int lastImage = 0;
|
||||
int fileCount = 0;
|
||||
foreach (const QString &fileName, outputDir.entryList(QStringList(QString("testclip_*")))) {
|
||||
int imgNumber = fileName.mid(5, fileName.size() - 9).toInt();
|
||||
lastImage = qMax(lastImage, imgNumber);
|
||||
if (outputDir.exists(fileName))
|
||||
fileCount += 1;
|
||||
}
|
||||
lastImage += fileCount;
|
||||
QUrl location(QDir::toNativeSeparators(outputDir.canonicalPath()
|
||||
+ QString("/testclip_%1").arg(lastImage + 1, 4, 10, QLatin1Char('0'))));
|
||||
return location;
|
||||
}
|
||||
|
||||
// This function returns the maximum possible sample value for a given audio format
|
||||
qreal getPeakValue(const QAudioFormat& format)
|
||||
{
|
||||
// Note: Only the most common sample formats are supported
|
||||
if (!format.isValid())
|
||||
return 0.0;
|
||||
|
||||
if (format.codec() != "audio/pcm")
|
||||
return 0.0;
|
||||
|
||||
switch (format.sampleType()) {
|
||||
case QAudioFormat::Unknown:
|
||||
break;
|
||||
case QAudioFormat::Float:
|
||||
if (format.sampleSize() != 32) // other sample formats are not supported
|
||||
return 0.0;
|
||||
return 1.00003;
|
||||
case QAudioFormat::SignedInt:
|
||||
if (format.sampleSize() == 32)
|
||||
return 2147483648.0;
|
||||
if (format.sampleSize() == 16)
|
||||
return 32768.0;
|
||||
if (format.sampleSize() == 8)
|
||||
return 128.0;
|
||||
break;
|
||||
case QAudioFormat::UnSignedInt:
|
||||
// Unsigned formats are not supported in this example
|
||||
break;
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
qreal getBufferLevel(const QAudioBuffer& buffer)
|
||||
{
|
||||
if (!buffer.format().isValid() || buffer.format().byteOrder() != QAudioFormat::LittleEndian)
|
||||
return 0.0;
|
||||
|
||||
if (buffer.format().codec() != "audio/pcm")
|
||||
return 0.0;
|
||||
|
||||
qreal peak_value = getPeakValue(buffer.format());
|
||||
if (qFuzzyCompare(peak_value, 0.0))
|
||||
return 0.0;
|
||||
|
||||
switch (buffer.format().sampleType()) {
|
||||
case QAudioFormat::Unknown:
|
||||
case QAudioFormat::UnSignedInt:
|
||||
break;
|
||||
case QAudioFormat::Float:
|
||||
if (buffer.format().sampleSize() == 32)
|
||||
return getBufferLevel(buffer.constData<float>(), buffer.sampleCount()) / peak_value;
|
||||
break;
|
||||
case QAudioFormat::SignedInt:
|
||||
if (buffer.format().sampleSize() == 32)
|
||||
return getBufferLevel(buffer.constData<long int>(), buffer.sampleCount()) / peak_value;
|
||||
if (buffer.format().sampleSize() == 16)
|
||||
return getBufferLevel(buffer.constData<short int>(), buffer.sampleCount()) / peak_value;
|
||||
if (buffer.format().sampleSize() == 8)
|
||||
return getBufferLevel(buffer.constData<signed char>(), buffer.sampleCount()) / peak_value;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
qreal getBufferLevel(const T *buffer, int samples)
|
||||
{
|
||||
qreal max_value = 0.0;
|
||||
|
||||
for (int i = 0; i < samples; ++i) {
|
||||
qreal value = qAbs(qreal(buffer[i]));
|
||||
if (value > max_value)
|
||||
max_value = value;
|
||||
}
|
||||
|
||||
return max_value;
|
||||
}
|
||||
|
||||
void AudioRecorder::processBuffer(const QAudioBuffer& buffer)
|
||||
{
|
||||
qreal level = getBufferLevel(buffer);
|
||||
ui->audioLevel->setLevel(level);
|
||||
}
|
||||
85
examples/multimedia/audiorecorder/audiorecorder.h
Normal file
85
examples/multimedia/audiorecorder/audiorecorder.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef AUDIORECORDER_H
|
||||
#define AUDIORECORDER_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QMediaRecorder>
|
||||
#include <QUrl>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui { class AudioRecorder; }
|
||||
class QAudioRecorder;
|
||||
class QAudioProbe;
|
||||
class QAudioBuffer;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class AudioRecorder : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AudioRecorder(QWidget *parent = 0);
|
||||
~AudioRecorder();
|
||||
|
||||
public slots:
|
||||
void processBuffer(const QAudioBuffer&);
|
||||
|
||||
private slots:
|
||||
void setOutputLocation();
|
||||
void togglePause();
|
||||
void toggleRecord();
|
||||
|
||||
void updateState(QMediaRecorder::State);
|
||||
void updateProgress(qint64 pos);
|
||||
void displayErrorMessage();
|
||||
QUrl generateAudioFilePath();
|
||||
|
||||
private:
|
||||
Ui::AudioRecorder *ui;
|
||||
|
||||
QAudioRecorder *audioRecorder;
|
||||
QAudioProbe *probe;
|
||||
bool outputLocationSet;
|
||||
|
||||
};
|
||||
|
||||
#endif // AUDIORECORDER_H
|
||||
26
examples/multimedia/audiorecorder/audiorecorder.pro
Normal file
26
examples/multimedia/audiorecorder/audiorecorder.pro
Normal file
@@ -0,0 +1,26 @@
|
||||
TEMPLATE = app
|
||||
TARGET = audiorecorder
|
||||
|
||||
QT += multimedia
|
||||
|
||||
win32:INCLUDEPATH += $$PWD
|
||||
|
||||
HEADERS = \
|
||||
audiorecorder.h \
|
||||
qaudiolevel.h
|
||||
|
||||
SOURCES = \
|
||||
main.cpp \
|
||||
audiorecorder.cpp \
|
||||
qaudiolevel.cpp
|
||||
|
||||
maemo*: {
|
||||
FORMS += audiorecorder_small.ui
|
||||
}else {
|
||||
FORMS += audiorecorder.ui
|
||||
}
|
||||
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/audiorecorder
|
||||
INSTALLS += target
|
||||
|
||||
QT+=widgets
|
||||
261
examples/multimedia/audiorecorder/audiorecorder.ui
Normal file
261
examples/multimedia/audiorecorder/audiorecorder.ui
Normal file
@@ -0,0 +1,261 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AudioRecorder</class>
|
||||
<widget class="QMainWindow" name="AudioRecorder">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>297</width>
|
||||
<height>374</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0" colspan="3">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Input Device:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="audioDeviceBox"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Audio Codec:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="audioCodecBox"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>File Container:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="containerBox"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Sample rate:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="sampleRateBox"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="3">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Encoding Mode:</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QRadioButton" name="constantQualityRadioButton">
|
||||
<property name="text">
|
||||
<string>Constant Quality:</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSlider" name="qualitySlider">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QRadioButton" name="constantBitrateRadioButton">
|
||||
<property name="text">
|
||||
<string>Constant Bitrate:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="bitrateBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="outputButton">
|
||||
<property name="text">
|
||||
<string>Output...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="recordButton">
|
||||
<property name="text">
|
||||
<string>Record</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QPushButton" name="pauseButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Pause</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="levelLabel">
|
||||
<property name="text">
|
||||
<string>Audio Level:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="-1">
|
||||
<widget class="QAudioLevel" name="audioLevel">
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>constantQualityRadioButton</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>qualitySlider</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>113</x>
|
||||
<y>197</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>115</x>
|
||||
<y>223</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>constantBitrateRadioButton</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>bitrateBox</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>173</x>
|
||||
<y>259</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>190</x>
|
||||
<y>291</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>outputButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>AudioRecorder</receiver>
|
||||
<slot>setOutputLocation()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>46</x>
|
||||
<y>340</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>6</x>
|
||||
<y>302</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>recordButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>AudioRecorder</receiver>
|
||||
<slot>toggleRecord()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>191</x>
|
||||
<y>340</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>113</x>
|
||||
<y>317</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>pauseButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>AudioRecorder</receiver>
|
||||
<slot>togglePause()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>252</x>
|
||||
<y>334</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>258</x>
|
||||
<y>346</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>setOutputLocation()</slot>
|
||||
<slot>toggleRecord()</slot>
|
||||
<slot>togglePause()</slot>
|
||||
</slots>
|
||||
</ui>
|
||||
266
examples/multimedia/audiorecorder/audiorecorder_small.ui
Normal file
266
examples/multimedia/audiorecorder/audiorecorder_small.ui
Normal file
@@ -0,0 +1,266 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AudioRecorder</class>
|
||||
<widget class="QMainWindow" name="AudioRecorder">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>420</width>
|
||||
<height>346</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="0" colspan="3">
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::ClickFocus</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>398</width>
|
||||
<height>275</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Input Device:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="audioDeviceBox"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Audio Codec:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="audioCodecBox"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>File Container:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="containerBox"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Sample rate:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="sampleRateBox"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="constantQualityRadioButton">
|
||||
<property name="text">
|
||||
<string>Quality:</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QRadioButton" name="constantBitrateRadioButton">
|
||||
<property name="text">
|
||||
<string>Bitrate:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QSlider" name="qualitySlider">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="bitrateBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>29</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="outputButton">
|
||||
<property name="text">
|
||||
<string>Output...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="recordButton">
|
||||
<property name="text">
|
||||
<string>Record</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QPushButton" name="pauseButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Pause</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>constantQualityRadioButton</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>qualitySlider</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>113</x>
|
||||
<y>197</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>115</x>
|
||||
<y>223</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>constantBitrateRadioButton</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>bitrateBox</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>173</x>
|
||||
<y>259</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>190</x>
|
||||
<y>291</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>outputButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>AudioRecorder</receiver>
|
||||
<slot>setOutputLocation()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>46</x>
|
||||
<y>340</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>6</x>
|
||||
<y>302</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>recordButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>AudioRecorder</receiver>
|
||||
<slot>toggleRecord()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>191</x>
|
||||
<y>340</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>113</x>
|
||||
<y>317</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>pauseButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>AudioRecorder</receiver>
|
||||
<slot>togglePause()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>252</x>
|
||||
<y>334</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>258</x>
|
||||
<y>346</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>setOutputLocation()</slot>
|
||||
<slot>toggleRecord()</slot>
|
||||
<slot>togglePause()</slot>
|
||||
</slots>
|
||||
</ui>
|
||||
BIN
examples/multimedia/audiorecorder/doc/images/audiorecorder.png
Normal file
BIN
examples/multimedia/audiorecorder/doc/images/audiorecorder.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
104
examples/multimedia/audiorecorder/doc/src/audiorecorder.qdoc
Normal file
104
examples/multimedia/audiorecorder/doc/src/audiorecorder.qdoc
Normal file
@@ -0,0 +1,104 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:FDL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Free Documentation License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Free
|
||||
** Documentation License version 1.3 as published by the Free Software
|
||||
** Foundation and appearing in the file included in the packaging of
|
||||
** this file. Please review the following information to ensure
|
||||
** the GNU Free Documentation License version 1.3 requirements
|
||||
** will be met: http://www.gnu.org/copyleft/fdl.html.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\example audiorecorder
|
||||
\title Audio Recorder Example
|
||||
\ingroup audio_examples
|
||||
\brief The Audio Recorder Example shows how to create a simple audio recorder.
|
||||
|
||||
It demonstrates the discovery of the supported devices and codecs and the use
|
||||
of recording functions in the QAudioRecorder class.
|
||||
|
||||
We display a window for the user to select the appropriate audio input,
|
||||
codec, container, and sample rate. Allow a setting of either quality or
|
||||
bitrate. Finally, the output file can be selected and recording can be
|
||||
started.
|
||||
|
||||
The lists are setup using the \l{QAudioRecorder::audioInputs()}{audioInputs()},
|
||||
\l{QAudioRecorder::supportedAudioCodecs()}{supportedAudioCodecs()},
|
||||
\l{QAudioRecorder::supportedContainers()}{supportedContainers()},
|
||||
\l{QAudioRecorder::supportedContainers()}{supportedContainers()}, and
|
||||
\l{QAudioRecorder::supportedAudioSampleRates()}{supportedAudioSampleRates()}
|
||||
methods. The quality slider is setup from 0 (zero) to
|
||||
\l{QMultimedia::VeryHighQuality} with a default value of
|
||||
\l{QMultimedia::NormalQuality}, while the bitrates are hardcoded
|
||||
into the list.
|
||||
|
||||
\image audiorecorder.png
|
||||
|
||||
To record audio we simply create a QAudioRecorder object.
|
||||
|
||||
\code
|
||||
audioRecorder = new QAudioRecorder(this);
|
||||
\endcode
|
||||
|
||||
And setup the lists as described above. The text on the record and pause
|
||||
buttons are toggled depending on the \l{QMediaRecorder::State}{state} of
|
||||
the \c audioRecorder object. This means that if the state is
|
||||
\l{QMediaRecorder::StoppedState} then the button text will be "Record" and
|
||||
"Pause". In \l{QMediaRecorder::RecordingState} the record button will have
|
||||
the text "Stop", and in \l{QMediaRecorder::PausedState} the pause button
|
||||
will have the text "Resume".
|
||||
|
||||
Pressing the buttons will also result in a toggle based on the state. If
|
||||
recording is stopped, then pressing the record button will setup the
|
||||
\l{QAudioEncoderSettings} based on the values of the selection lists,
|
||||
will set the encoding settings and container on the \c audioRecorder
|
||||
object, and start recording using the
|
||||
\l{QMediaRecorder::record()}{record()} method.
|
||||
|
||||
\code
|
||||
QAudioEncoderSettings settings;
|
||||
settings.setCodec(boxValue(ui->audioCodecBox).toString());
|
||||
settings.setSampleRate(boxValue(ui->sampleRateBox).toInt());
|
||||
settings.setBitRate(boxValue(ui->bitrateBox).toInt());
|
||||
settings.setQuality(QMultimedia::EncodingQuality(ui->qualitySlider->value()));
|
||||
settings.setEncodingMode(ui->constantQualityRadioButton->isChecked() ?
|
||||
QMultimedia::ConstantQualityEncoding :
|
||||
QMultimedia::ConstantBitRateEncoding);
|
||||
|
||||
QString container = boxValue(ui->containerBox).toString();
|
||||
|
||||
audioRecorder->setEncodingSettings(settings, QVideoEncoderSettings(), container);
|
||||
audioRecorder->record();
|
||||
\endcode
|
||||
|
||||
While recording, the status bar of the application is updated with duration information
|
||||
from the \l{QMediaRecorder::durationChanged()}{durationChanged} signal from the
|
||||
\c audioRecorder object.
|
||||
|
||||
\code
|
||||
ui->statusbar->showMessage(tr("Recorded %1 sec").arg(duration / 1000));
|
||||
\endcode
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
53
examples/multimedia/audiorecorder/main.cpp
Normal file
53
examples/multimedia/audiorecorder/main.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "audiorecorder.h"
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
AudioRecorder recorder;
|
||||
recorder.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
68
examples/multimedia/audiorecorder/qaudiolevel.cpp
Normal file
68
examples/multimedia/audiorecorder/qaudiolevel.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qaudiolevel.h"
|
||||
#include <QPainter>
|
||||
|
||||
QAudioLevel::QAudioLevel(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_level(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
void QAudioLevel::setLevel(qreal level)
|
||||
{
|
||||
if (m_level != level) {
|
||||
m_level = level;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void QAudioLevel::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
||||
QPainter painter(this);
|
||||
// draw level
|
||||
qreal widthLevel = m_level * width();
|
||||
painter.fillRect(0, 0, widthLevel, height(), Qt::red);
|
||||
// clear the rest of the control
|
||||
painter.fillRect(widthLevel, 0, width(), height(), Qt::black);
|
||||
}
|
||||
62
examples/multimedia/audiorecorder/qaudiolevel.h
Normal file
62
examples/multimedia/audiorecorder/qaudiolevel.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QAUDIOLEVEL_H
|
||||
#define QAUDIOLEVEL_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QAudioLevel : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QAudioLevel(QWidget *parent = 0);
|
||||
|
||||
// Using [0; 1.0] range
|
||||
void setLevel(qreal level);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event);
|
||||
|
||||
private:
|
||||
qreal m_level;
|
||||
};
|
||||
|
||||
#endif // QAUDIOLEVEL_H
|
||||
@@ -0,0 +1,9 @@
|
||||
QT += qml quick multimedia
|
||||
|
||||
SOURCES += main.cpp
|
||||
RESOURCES += declarative-radio.qrc
|
||||
|
||||
EXAMPLE_FILES += view.qml
|
||||
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/declarative-radio
|
||||
INSTALLS += target
|
||||
@@ -0,0 +1,6 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
<file>view.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
@@ -0,0 +1,35 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:FDL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Free Documentation License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Free
|
||||
** Documentation License version 1.3 as published by the Free Software
|
||||
** Foundation and appearing in the file included in the packaging of
|
||||
** this file. Please review the following information to ensure
|
||||
** the GNU Free Documentation License version 1.3 requirements
|
||||
** will be met: http://www.gnu.org/copyleft/fdl.html.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\example declarative-radio
|
||||
\title Declarative Radio Example
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
58
examples/multimedia/declarative-radio/main.cpp
Normal file
58
examples/multimedia/declarative-radio/main.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the demonstration applications of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QGuiApplication>
|
||||
|
||||
#include <qqml.h>
|
||||
#include <QtQuick/qquickview.h>
|
||||
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
QGuiApplication app(argc, argv);
|
||||
|
||||
QQuickView view;
|
||||
|
||||
view.setSource(QUrl("qrc:view.qml"));
|
||||
view.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
191
examples/multimedia/declarative-radio/view.qml
Normal file
191
examples/multimedia/declarative-radio/view.qml
Normal file
@@ -0,0 +1,191 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.0
|
||||
import QtMultimedia 5.0
|
||||
|
||||
Rectangle {
|
||||
width: 400; height: 300;
|
||||
|
||||
Radio {
|
||||
id: radio
|
||||
band: Radio.FM
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 5
|
||||
spacing: 5
|
||||
|
||||
Row {
|
||||
|
||||
Text {
|
||||
id: freq
|
||||
|
||||
width: 150
|
||||
height: 200
|
||||
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: "" + radio.frequency / 1000 + " kHz"
|
||||
}
|
||||
Text {
|
||||
id: sig
|
||||
|
||||
width: 200
|
||||
height: 200
|
||||
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: (radio.availability == Radio.Available ? "No Signal " : "No Radio Found")
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
spacing: 5
|
||||
|
||||
Rectangle {
|
||||
width: 350
|
||||
height: 10
|
||||
|
||||
color: "black"
|
||||
|
||||
Rectangle {
|
||||
width: 5
|
||||
height: 10
|
||||
color: "red"
|
||||
|
||||
y: 0
|
||||
x: (parent.width - 5) * ((radio.frequency - radio.minimumFrequency) / (radio.maximumFrequency -
|
||||
radio.minimumFrequency))
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Row {
|
||||
spacing: 5
|
||||
|
||||
Rectangle {
|
||||
id: scanDownButton
|
||||
border.color: "black"
|
||||
border.width: 1
|
||||
radius: 2
|
||||
|
||||
width: 90
|
||||
height: 40
|
||||
|
||||
Text {
|
||||
anchors.fill: parent
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: "Scan Down"
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: radio.scanDown();
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
id: freqDownButton
|
||||
border.color: "black"
|
||||
border.width: 1
|
||||
radius: 2
|
||||
|
||||
width: 90
|
||||
height: 40
|
||||
|
||||
Text {
|
||||
anchors.fill: parent
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: "Freq Down"
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: radio.tuneDown();
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
id: freqUpButton
|
||||
border.color: "black"
|
||||
border.width: 1
|
||||
radius: 2
|
||||
|
||||
width: 90
|
||||
height: 40
|
||||
|
||||
Text {
|
||||
anchors.fill: parent
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: "Freq Up"
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: radio.tuneUp();
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
id: scanUpButton
|
||||
border.color: "black"
|
||||
border.width: 1
|
||||
radius: 2
|
||||
|
||||
width: 90
|
||||
height: 40
|
||||
|
||||
Text {
|
||||
anchors.fill: parent
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: "Scan Up"
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: radio.scanUp();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
25
examples/multimedia/multimedia.pro
Normal file
25
examples/multimedia/multimedia.pro
Normal file
@@ -0,0 +1,25 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += audiodecoder
|
||||
|
||||
# These examples all need widgets for now (using creator templates that use widgets)
|
||||
!isEmpty(QT.widgets.name) {
|
||||
SUBDIRS += \
|
||||
radio \
|
||||
spectrum \
|
||||
audiorecorder \
|
||||
audiodevices \
|
||||
audioinput \
|
||||
audiooutput \
|
||||
|
||||
QT += widgets
|
||||
}
|
||||
|
||||
!isEmpty(QT.gui.name):!isEmpty(QT.qml.name) {
|
||||
SUBDIRS += \
|
||||
declarative-radio \
|
||||
video
|
||||
}
|
||||
|
||||
config_openal: SUBDIRS += audioengine
|
||||
|
||||
53
examples/multimedia/radio/main.cpp
Normal file
53
examples/multimedia/radio/main.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "radio.h"
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
Radio radio;
|
||||
radio.show();
|
||||
|
||||
return app.exec();
|
||||
};
|
||||
158
examples/multimedia/radio/radio.cpp
Normal file
158
examples/multimedia/radio/radio.cpp
Normal file
@@ -0,0 +1,158 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "radio.h"
|
||||
|
||||
Radio::Radio()
|
||||
{
|
||||
radio = new QRadioTuner;
|
||||
connect(radio, SIGNAL(error(QRadioTuner::Error)), this, SLOT(error(QRadioTuner::Error)));
|
||||
|
||||
if (radio->isBandSupported(QRadioTuner::FM))
|
||||
radio->setBand(QRadioTuner::FM);
|
||||
|
||||
QWidget *window = new QWidget;
|
||||
QVBoxLayout *layout = new QVBoxLayout;
|
||||
QHBoxLayout *buttonBar = new QHBoxLayout;
|
||||
QHBoxLayout *topBar = new QHBoxLayout;
|
||||
|
||||
layout->addLayout(topBar);
|
||||
|
||||
freq = new QLabel;
|
||||
freq->setText(QString("%1 kHz").arg(radio->frequency()/1000));
|
||||
topBar->addWidget(freq);
|
||||
connect(radio, SIGNAL(frequencyChanged(int)), SLOT(freqChanged(int)));
|
||||
|
||||
signal = new QLabel;
|
||||
if (radio->isAvailable())
|
||||
signal->setText(tr("No Signal"));
|
||||
else
|
||||
signal->setText(tr("No radio found"));
|
||||
topBar->addWidget(signal);
|
||||
connect(radio, SIGNAL(signalStrengthChanged(int)), SLOT(signalChanged(int)));
|
||||
|
||||
volumeSlider = new QSlider(Qt::Vertical,this);
|
||||
volumeSlider->setRange(0, 100);
|
||||
volumeSlider->setValue(50);
|
||||
connect(volumeSlider, SIGNAL(valueChanged(int)), SLOT(updateVolume(int)));
|
||||
topBar->addWidget(volumeSlider);
|
||||
|
||||
layout->addLayout(buttonBar);
|
||||
|
||||
searchLeft = new QPushButton;
|
||||
searchLeft->setText(tr("scan Down"));
|
||||
connect(searchLeft, SIGNAL(clicked()), SLOT(searchDown()));
|
||||
buttonBar->addWidget(searchLeft);
|
||||
|
||||
left = new QPushButton;
|
||||
left->setText(tr("Freq Down"));
|
||||
connect(left, SIGNAL(clicked()), SLOT(freqDown()));
|
||||
buttonBar->addWidget(left);
|
||||
|
||||
right = new QPushButton;
|
||||
connect(right, SIGNAL(clicked()), SLOT(freqUp()));
|
||||
right->setText(tr("Freq Up"));
|
||||
buttonBar->addWidget(right);
|
||||
|
||||
searchRight = new QPushButton;
|
||||
searchRight->setText(tr("scan Up"));
|
||||
connect(searchRight, SIGNAL(clicked()), SLOT(searchUp()));
|
||||
buttonBar->addWidget(searchRight);
|
||||
|
||||
window->setLayout(layout);
|
||||
setCentralWidget(window);
|
||||
window->show();
|
||||
|
||||
radio->start();
|
||||
}
|
||||
|
||||
Radio::~Radio()
|
||||
{
|
||||
}
|
||||
|
||||
void Radio::freqUp()
|
||||
{
|
||||
int f = radio->frequency();
|
||||
f += radio->frequencyStep(QRadioTuner::FM);
|
||||
radio->setFrequency(f);
|
||||
}
|
||||
|
||||
void Radio::freqDown()
|
||||
{
|
||||
int f = radio->frequency();
|
||||
f -= radio->frequencyStep(QRadioTuner::FM);
|
||||
radio->setFrequency(f);
|
||||
}
|
||||
|
||||
void Radio::searchUp()
|
||||
{
|
||||
radio->searchForward();
|
||||
}
|
||||
|
||||
void Radio::searchDown()
|
||||
{
|
||||
radio->searchBackward();
|
||||
}
|
||||
|
||||
void Radio::freqChanged(int)
|
||||
{
|
||||
freq->setText(QString("%1 kHz").arg(radio->frequency()/1000));
|
||||
}
|
||||
|
||||
void Radio::signalChanged(int)
|
||||
{
|
||||
if(radio->signalStrength() > 25)
|
||||
signal->setText(tr("Got Signal"));
|
||||
else
|
||||
signal->setText(tr("No Signal"));
|
||||
}
|
||||
|
||||
void Radio::updateVolume(int v)
|
||||
{
|
||||
radio->setVolume(v);
|
||||
}
|
||||
|
||||
void Radio::error(QRadioTuner::Error error)
|
||||
{
|
||||
const QMetaObject *metaObj = radio->metaObject();
|
||||
QMetaEnum errorEnum = metaObj->enumerator(metaObj->indexOfEnumerator("Error"));
|
||||
qWarning().nospace() << "Warning: Example application received error QRadioTuner::" << errorEnum.valueToKey(error);
|
||||
}
|
||||
|
||||
75
examples/multimedia/radio/radio.h
Normal file
75
examples/multimedia/radio/radio.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef RADIO_H
|
||||
#define RADIO_H
|
||||
|
||||
#include <QtWidgets>
|
||||
#include <QRadioTuner>
|
||||
|
||||
class Radio : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Radio();
|
||||
~Radio();
|
||||
|
||||
public slots:
|
||||
void freqUp();
|
||||
void freqDown();
|
||||
void searchUp();
|
||||
void searchDown();
|
||||
void freqChanged(int f);
|
||||
void signalChanged(int s);
|
||||
void updateVolume(int v);
|
||||
void error(QRadioTuner::Error error);
|
||||
|
||||
private:
|
||||
QLabel *freq;
|
||||
QLabel *signal;
|
||||
QPushButton *left;
|
||||
QPushButton *right;
|
||||
QPushButton *searchLeft;
|
||||
QPushButton *searchRight;
|
||||
QSlider *volumeSlider;
|
||||
QRadioTuner *radio;
|
||||
};
|
||||
|
||||
#endif // RADIO_H
|
||||
16
examples/multimedia/radio/radio.pro
Normal file
16
examples/multimedia/radio/radio.pro
Normal file
@@ -0,0 +1,16 @@
|
||||
TEMPLATE = app
|
||||
TARGET = radio
|
||||
|
||||
QT += multimedia
|
||||
|
||||
HEADERS = \
|
||||
radio.h
|
||||
|
||||
SOURCES = \
|
||||
main.cpp \
|
||||
radio.cpp
|
||||
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/radio
|
||||
INSTALLS += target
|
||||
|
||||
QT+=widgets
|
||||
97
examples/multimedia/spectrum/3rdparty/fftreal/Array.h
vendored
Normal file
97
examples/multimedia/spectrum/3rdparty/fftreal/Array.h
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Array.h
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if ! defined (Array_HEADER_INCLUDED)
|
||||
#define Array_HEADER_INCLUDED
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma once
|
||||
#pragma warning (4 : 4250) // "Inherits via dominance."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
template <class T, long LEN>
|
||||
class Array
|
||||
{
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
public:
|
||||
|
||||
typedef T DataType;
|
||||
|
||||
Array ();
|
||||
|
||||
inline const DataType &
|
||||
operator [] (long pos) const;
|
||||
inline DataType &
|
||||
operator [] (long pos);
|
||||
|
||||
static inline long
|
||||
size ();
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
DataType _data_arr [LEN];
|
||||
|
||||
|
||||
|
||||
/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
Array (const Array &other);
|
||||
Array & operator = (const Array &other);
|
||||
bool operator == (const Array &other);
|
||||
bool operator != (const Array &other);
|
||||
|
||||
}; // class Array
|
||||
|
||||
|
||||
|
||||
#include "Array.hpp"
|
||||
|
||||
|
||||
|
||||
#endif // Array_HEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
98
examples/multimedia/spectrum/3rdparty/fftreal/Array.hpp
vendored
Normal file
98
examples/multimedia/spectrum/3rdparty/fftreal/Array.hpp
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Array.hpp
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if defined (Array_CURRENT_CODEHEADER)
|
||||
#error Recursive inclusion of Array code header.
|
||||
#endif
|
||||
#define Array_CURRENT_CODEHEADER
|
||||
|
||||
#if ! defined (Array_CODEHEADER_INCLUDED)
|
||||
#define Array_CODEHEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
template <class T, long LEN>
|
||||
Array <T, LEN>::Array ()
|
||||
{
|
||||
// Nothing
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T, long LEN>
|
||||
const typename Array <T, LEN>::DataType & Array <T, LEN>::operator [] (long pos) const
|
||||
{
|
||||
assert (pos >= 0);
|
||||
assert (pos < LEN);
|
||||
|
||||
return (_data_arr [pos]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T, long LEN>
|
||||
typename Array <T, LEN>::DataType & Array <T, LEN>::operator [] (long pos)
|
||||
{
|
||||
assert (pos >= 0);
|
||||
assert (pos < LEN);
|
||||
|
||||
return (_data_arr [pos]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T, long LEN>
|
||||
long Array <T, LEN>::size ()
|
||||
{
|
||||
return (LEN);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
#endif // Array_CODEHEADER_INCLUDED
|
||||
|
||||
#undef Array_CURRENT_CODEHEADER
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
100
examples/multimedia/spectrum/3rdparty/fftreal/DynArray.h
vendored
Normal file
100
examples/multimedia/spectrum/3rdparty/fftreal/DynArray.h
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
/*****************************************************************************
|
||||
|
||||
DynArray.h
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if ! defined (DynArray_HEADER_INCLUDED)
|
||||
#define DynArray_HEADER_INCLUDED
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma once
|
||||
#pragma warning (4 : 4250) // "Inherits via dominance."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
class DynArray
|
||||
{
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
public:
|
||||
|
||||
typedef T DataType;
|
||||
|
||||
DynArray ();
|
||||
explicit DynArray (long size);
|
||||
~DynArray ();
|
||||
|
||||
inline long size () const;
|
||||
inline void resize (long size);
|
||||
|
||||
inline const DataType &
|
||||
operator [] (long pos) const;
|
||||
inline DataType &
|
||||
operator [] (long pos);
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
DataType * _data_ptr;
|
||||
long _len;
|
||||
|
||||
|
||||
|
||||
/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
DynArray (const DynArray &other);
|
||||
DynArray & operator = (const DynArray &other);
|
||||
bool operator == (const DynArray &other);
|
||||
bool operator != (const DynArray &other);
|
||||
|
||||
}; // class DynArray
|
||||
|
||||
|
||||
|
||||
#include "DynArray.hpp"
|
||||
|
||||
|
||||
|
||||
#endif // DynArray_HEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
143
examples/multimedia/spectrum/3rdparty/fftreal/DynArray.hpp
vendored
Normal file
143
examples/multimedia/spectrum/3rdparty/fftreal/DynArray.hpp
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
/*****************************************************************************
|
||||
|
||||
DynArray.hpp
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if defined (DynArray_CURRENT_CODEHEADER)
|
||||
#error Recursive inclusion of DynArray code header.
|
||||
#endif
|
||||
#define DynArray_CURRENT_CODEHEADER
|
||||
|
||||
#if ! defined (DynArray_CODEHEADER_INCLUDED)
|
||||
#define DynArray_CODEHEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
DynArray <T>::DynArray ()
|
||||
: _data_ptr (0)
|
||||
, _len (0)
|
||||
{
|
||||
// Nothing
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
DynArray <T>::DynArray (long size)
|
||||
: _data_ptr (0)
|
||||
, _len (0)
|
||||
{
|
||||
assert (size >= 0);
|
||||
if (size > 0)
|
||||
{
|
||||
_data_ptr = new DataType [size];
|
||||
_len = size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
DynArray <T>::~DynArray ()
|
||||
{
|
||||
delete [] _data_ptr;
|
||||
_data_ptr = 0;
|
||||
_len = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
long DynArray <T>::size () const
|
||||
{
|
||||
return (_len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
void DynArray <T>::resize (long size)
|
||||
{
|
||||
assert (size >= 0);
|
||||
if (size > 0)
|
||||
{
|
||||
DataType * old_data_ptr = _data_ptr;
|
||||
DataType * tmp_data_ptr = new DataType [size];
|
||||
|
||||
_data_ptr = tmp_data_ptr;
|
||||
_len = size;
|
||||
|
||||
delete [] old_data_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
const typename DynArray <T>::DataType & DynArray <T>::operator [] (long pos) const
|
||||
{
|
||||
assert (pos >= 0);
|
||||
assert (pos < _len);
|
||||
|
||||
return (_data_ptr [pos]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
typename DynArray <T>::DataType & DynArray <T>::operator [] (long pos)
|
||||
{
|
||||
assert (pos >= 0);
|
||||
assert (pos < _len);
|
||||
|
||||
return (_data_ptr [pos]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
#endif // DynArray_CODEHEADER_INCLUDED
|
||||
|
||||
#undef DynArray_CURRENT_CODEHEADER
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
273
examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.dsp
vendored
Normal file
273
examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.dsp
vendored
Normal file
@@ -0,0 +1,273 @@
|
||||
# Microsoft Developer Studio Project File - Name="FFTReal" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=FFTReal - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "FFTReal.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "FFTReal.mak" CFG="FFTReal - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "FFTReal - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "FFTReal - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "FFTReal - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GR /GX /O2 /Ob2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x40c /d "NDEBUG"
|
||||
# ADD RSC /l 0x40c /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "FFTReal - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /G6 /MTd /W3 /Gm /GR /GX /Zi /Od /Gf /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
|
||||
# ADD BASE RSC /l 0x40c /d "_DEBUG"
|
||||
# ADD RSC /l 0x40c /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "FFTReal - Win32 Release"
|
||||
# Name "FFTReal - Win32 Debug"
|
||||
# Begin Group "Library"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Array.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Array.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\def.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DynArray.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DynArray.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\FFTReal.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\FFTReal.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\FFTRealFixLen.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\FFTRealFixLen.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\FFTRealFixLenParam.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\FFTRealPassDirect.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\FFTRealPassDirect.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\FFTRealPassInverse.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\FFTRealPassInverse.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\FFTRealSelect.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\FFTRealSelect.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\FFTRealUseTrigo.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\FFTRealUseTrigo.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\OscSinCos.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\OscSinCos.hpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Test"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Group "stopwatch"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\stopwatch\ClockCycleCounter.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\stopwatch\ClockCycleCounter.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\stopwatch\ClockCycleCounter.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\stopwatch\def.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\stopwatch\fnc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\stopwatch\fnc.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\stopwatch\Int64.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\stopwatch\StopWatch.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\stopwatch\StopWatch.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\stopwatch\StopWatch.hpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\test.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\test_fnc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\test_fnc.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\test_settings.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TestAccuracy.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TestAccuracy.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TestHelperFixLen.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TestHelperFixLen.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TestHelperNormal.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TestHelperNormal.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TestSpeed.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TestSpeed.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TestWhiteNoiseGen.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TestWhiteNoiseGen.hpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
29
examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.dsw
vendored
Normal file
29
examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.dsw
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "FFTReal"=.\FFTReal.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
142
examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.h
vendored
Normal file
142
examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.h
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
/*****************************************************************************
|
||||
|
||||
FFTReal.h
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if ! defined (FFTReal_HEADER_INCLUDED)
|
||||
#define FFTReal_HEADER_INCLUDED
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma once
|
||||
#pragma warning (4 : 4250) // "Inherits via dominance."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include "def.h"
|
||||
#include "DynArray.h"
|
||||
#include "OscSinCos.h"
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
class FFTReal
|
||||
{
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
public:
|
||||
|
||||
enum { MAX_BIT_DEPTH = 30 }; // So length can be represented as long int
|
||||
|
||||
typedef DT DataType;
|
||||
|
||||
explicit FFTReal (long length);
|
||||
virtual ~FFTReal () {}
|
||||
|
||||
long get_length () const;
|
||||
void do_fft (DataType f [], const DataType x []) const;
|
||||
void do_ifft (const DataType f [], DataType x []) const;
|
||||
void rescale (DataType x []) const;
|
||||
DataType * use_buffer () const;
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
// Over this bit depth, we use direct calculation for sin/cos
|
||||
enum { TRIGO_BD_LIMIT = 12 };
|
||||
|
||||
typedef OscSinCos <DataType> OscType;
|
||||
|
||||
void init_br_lut ();
|
||||
void init_trigo_lut ();
|
||||
void init_trigo_osc ();
|
||||
|
||||
FORCEINLINE const long *
|
||||
get_br_ptr () const;
|
||||
FORCEINLINE const DataType *
|
||||
get_trigo_ptr (int level) const;
|
||||
FORCEINLINE long
|
||||
get_trigo_level_index (int level) const;
|
||||
|
||||
inline void compute_fft_general (DataType f [], const DataType x []) const;
|
||||
inline void compute_direct_pass_1_2 (DataType df [], const DataType x []) const;
|
||||
inline void compute_direct_pass_3 (DataType df [], const DataType sf []) const;
|
||||
inline void compute_direct_pass_n (DataType df [], const DataType sf [], int pass) const;
|
||||
inline void compute_direct_pass_n_lut (DataType df [], const DataType sf [], int pass) const;
|
||||
inline void compute_direct_pass_n_osc (DataType df [], const DataType sf [], int pass) const;
|
||||
|
||||
inline void compute_ifft_general (const DataType f [], DataType x []) const;
|
||||
inline void compute_inverse_pass_n (DataType df [], const DataType sf [], int pass) const;
|
||||
inline void compute_inverse_pass_n_osc (DataType df [], const DataType sf [], int pass) const;
|
||||
inline void compute_inverse_pass_n_lut (DataType df [], const DataType sf [], int pass) const;
|
||||
inline void compute_inverse_pass_3 (DataType df [], const DataType sf []) const;
|
||||
inline void compute_inverse_pass_1_2 (DataType x [], const DataType sf []) const;
|
||||
|
||||
const long _length;
|
||||
const int _nbr_bits;
|
||||
DynArray <long>
|
||||
_br_lut;
|
||||
DynArray <DataType>
|
||||
_trigo_lut;
|
||||
mutable DynArray <DataType>
|
||||
_buffer;
|
||||
mutable DynArray <OscType>
|
||||
_trigo_osc;
|
||||
|
||||
|
||||
|
||||
/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
FFTReal ();
|
||||
FFTReal (const FFTReal &other);
|
||||
FFTReal & operator = (const FFTReal &other);
|
||||
bool operator == (const FFTReal &other);
|
||||
bool operator != (const FFTReal &other);
|
||||
|
||||
}; // class FFTReal
|
||||
|
||||
|
||||
|
||||
#include "FFTReal.hpp"
|
||||
|
||||
|
||||
|
||||
#endif // FFTReal_HEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
916
examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.hpp
vendored
Normal file
916
examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.hpp
vendored
Normal file
@@ -0,0 +1,916 @@
|
||||
/*****************************************************************************
|
||||
|
||||
FFTReal.hpp
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if defined (FFTReal_CURRENT_CODEHEADER)
|
||||
#error Recursive inclusion of FFTReal code header.
|
||||
#endif
|
||||
#define FFTReal_CURRENT_CODEHEADER
|
||||
|
||||
#if ! defined (FFTReal_CODEHEADER_INCLUDED)
|
||||
#define FFTReal_CODEHEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
|
||||
|
||||
|
||||
static inline bool FFTReal_is_pow2 (long x)
|
||||
{
|
||||
assert (x > 0);
|
||||
|
||||
return ((x & -x) == x);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline int FFTReal_get_next_pow2 (long x)
|
||||
{
|
||||
--x;
|
||||
|
||||
int p = 0;
|
||||
while ((x & ~0xFFFFL) != 0)
|
||||
{
|
||||
p += 16;
|
||||
x >>= 16;
|
||||
}
|
||||
while ((x & ~0xFL) != 0)
|
||||
{
|
||||
p += 4;
|
||||
x >>= 4;
|
||||
}
|
||||
while (x > 0)
|
||||
{
|
||||
++p;
|
||||
x >>= 1;
|
||||
}
|
||||
|
||||
return (p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
Name: ctor
|
||||
Input parameters:
|
||||
- length: length of the array on which we want to do a FFT. Range: power of
|
||||
2 only, > 0.
|
||||
Throws: std::bad_alloc
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
template <class DT>
|
||||
FFTReal <DT>::FFTReal (long length)
|
||||
: _length (length)
|
||||
, _nbr_bits (FFTReal_get_next_pow2 (length))
|
||||
, _br_lut ()
|
||||
, _trigo_lut ()
|
||||
, _buffer (length)
|
||||
, _trigo_osc ()
|
||||
{
|
||||
assert (FFTReal_is_pow2 (length));
|
||||
assert (_nbr_bits <= MAX_BIT_DEPTH);
|
||||
|
||||
init_br_lut ();
|
||||
init_trigo_lut ();
|
||||
init_trigo_osc ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
Name: get_length
|
||||
Description:
|
||||
Returns the number of points processed by this FFT object.
|
||||
Returns: The number of points, power of 2, > 0.
|
||||
Throws: Nothing
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
template <class DT>
|
||||
long FFTReal <DT>::get_length () const
|
||||
{
|
||||
return (_length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
Name: do_fft
|
||||
Description:
|
||||
Compute the FFT of the array.
|
||||
Input parameters:
|
||||
- x: pointer on the source array (time).
|
||||
Output parameters:
|
||||
- f: pointer on the destination array (frequencies).
|
||||
f [0...length(x)/2] = real values,
|
||||
f [length(x)/2+1...length(x)-1] = negative imaginary values of
|
||||
coefficents 1...length(x)/2-1.
|
||||
Throws: Nothing
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
template <class DT>
|
||||
void FFTReal <DT>::do_fft (DataType f [], const DataType x []) const
|
||||
{
|
||||
assert (f != 0);
|
||||
assert (f != use_buffer ());
|
||||
assert (x != 0);
|
||||
assert (x != use_buffer ());
|
||||
assert (x != f);
|
||||
|
||||
// General case
|
||||
if (_nbr_bits > 2)
|
||||
{
|
||||
compute_fft_general (f, x);
|
||||
}
|
||||
|
||||
// 4-point FFT
|
||||
else if (_nbr_bits == 2)
|
||||
{
|
||||
f [1] = x [0] - x [2];
|
||||
f [3] = x [1] - x [3];
|
||||
|
||||
const DataType b_0 = x [0] + x [2];
|
||||
const DataType b_2 = x [1] + x [3];
|
||||
|
||||
f [0] = b_0 + b_2;
|
||||
f [2] = b_0 - b_2;
|
||||
}
|
||||
|
||||
// 2-point FFT
|
||||
else if (_nbr_bits == 1)
|
||||
{
|
||||
f [0] = x [0] + x [1];
|
||||
f [1] = x [0] - x [1];
|
||||
}
|
||||
|
||||
// 1-point FFT
|
||||
else
|
||||
{
|
||||
f [0] = x [0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
Name: do_ifft
|
||||
Description:
|
||||
Compute the inverse FFT of the array. Note that data must be post-scaled:
|
||||
IFFT (FFT (x)) = x * length (x).
|
||||
Input parameters:
|
||||
- f: pointer on the source array (frequencies).
|
||||
f [0...length(x)/2] = real values
|
||||
f [length(x)/2+1...length(x)-1] = negative imaginary values of
|
||||
coefficents 1...length(x)/2-1.
|
||||
Output parameters:
|
||||
- x: pointer on the destination array (time).
|
||||
Throws: Nothing
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
template <class DT>
|
||||
void FFTReal <DT>::do_ifft (const DataType f [], DataType x []) const
|
||||
{
|
||||
assert (f != 0);
|
||||
assert (f != use_buffer ());
|
||||
assert (x != 0);
|
||||
assert (x != use_buffer ());
|
||||
assert (x != f);
|
||||
|
||||
// General case
|
||||
if (_nbr_bits > 2)
|
||||
{
|
||||
compute_ifft_general (f, x);
|
||||
}
|
||||
|
||||
// 4-point IFFT
|
||||
else if (_nbr_bits == 2)
|
||||
{
|
||||
const DataType b_0 = f [0] + f [2];
|
||||
const DataType b_2 = f [0] - f [2];
|
||||
|
||||
x [0] = b_0 + f [1] * 2;
|
||||
x [2] = b_0 - f [1] * 2;
|
||||
x [1] = b_2 + f [3] * 2;
|
||||
x [3] = b_2 - f [3] * 2;
|
||||
}
|
||||
|
||||
// 2-point IFFT
|
||||
else if (_nbr_bits == 1)
|
||||
{
|
||||
x [0] = f [0] + f [1];
|
||||
x [1] = f [0] - f [1];
|
||||
}
|
||||
|
||||
// 1-point IFFT
|
||||
else
|
||||
{
|
||||
x [0] = f [0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
Name: rescale
|
||||
Description:
|
||||
Scale an array by divide each element by its length. This function should
|
||||
be called after FFT + IFFT.
|
||||
Input parameters:
|
||||
- x: pointer on array to rescale (time or frequency).
|
||||
Throws: Nothing
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
template <class DT>
|
||||
void FFTReal <DT>::rescale (DataType x []) const
|
||||
{
|
||||
const DataType mul = DataType (1.0 / _length);
|
||||
|
||||
if (_length < 4)
|
||||
{
|
||||
long i = _length - 1;
|
||||
do
|
||||
{
|
||||
x [i] *= mul;
|
||||
--i;
|
||||
}
|
||||
while (i >= 0);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
assert ((_length & 3) == 0);
|
||||
|
||||
// Could be optimized with SIMD instruction sets (needs alignment check)
|
||||
long i = _length - 4;
|
||||
do
|
||||
{
|
||||
x [i + 0] *= mul;
|
||||
x [i + 1] *= mul;
|
||||
x [i + 2] *= mul;
|
||||
x [i + 3] *= mul;
|
||||
i -= 4;
|
||||
}
|
||||
while (i >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
Name: use_buffer
|
||||
Description:
|
||||
Access the internal buffer, whose length is the FFT one.
|
||||
Buffer content will be erased at each do_fft() / do_ifft() call!
|
||||
This buffer cannot be used as:
|
||||
- source for FFT or IFFT done with this object
|
||||
- destination for FFT or IFFT done with this object
|
||||
Returns:
|
||||
Buffer start address
|
||||
Throws: Nothing
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
template <class DT>
|
||||
typename FFTReal <DT>::DataType * FFTReal <DT>::use_buffer () const
|
||||
{
|
||||
return (&_buffer [0]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
void FFTReal <DT>::init_br_lut ()
|
||||
{
|
||||
const long length = 1L << _nbr_bits;
|
||||
_br_lut.resize (length);
|
||||
|
||||
_br_lut [0] = 0;
|
||||
long br_index = 0;
|
||||
for (long cnt = 1; cnt < length; ++cnt)
|
||||
{
|
||||
// ++br_index (bit reversed)
|
||||
long bit = length >> 1;
|
||||
while (((br_index ^= bit) & bit) == 0)
|
||||
{
|
||||
bit >>= 1;
|
||||
}
|
||||
|
||||
_br_lut [cnt] = br_index;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
void FFTReal <DT>::init_trigo_lut ()
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
if (_nbr_bits > 3)
|
||||
{
|
||||
const long total_len = (1L << (_nbr_bits - 1)) - 4;
|
||||
_trigo_lut.resize (total_len);
|
||||
|
||||
for (int level = 3; level < _nbr_bits; ++level)
|
||||
{
|
||||
const long level_len = 1L << (level - 1);
|
||||
DataType * const level_ptr =
|
||||
&_trigo_lut [get_trigo_level_index (level)];
|
||||
const double mul = PI / (level_len << 1);
|
||||
|
||||
for (long i = 0; i < level_len; ++ i)
|
||||
{
|
||||
level_ptr [i] = static_cast <DataType> (cos (i * mul));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
void FFTReal <DT>::init_trigo_osc ()
|
||||
{
|
||||
const int nbr_osc = _nbr_bits - TRIGO_BD_LIMIT;
|
||||
if (nbr_osc > 0)
|
||||
{
|
||||
_trigo_osc.resize (nbr_osc);
|
||||
|
||||
for (int osc_cnt = 0; osc_cnt < nbr_osc; ++osc_cnt)
|
||||
{
|
||||
OscType & osc = _trigo_osc [osc_cnt];
|
||||
|
||||
const long len = 1L << (TRIGO_BD_LIMIT + osc_cnt);
|
||||
const double mul = (0.5 * PI) / len;
|
||||
osc.set_step (mul);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
const long * FFTReal <DT>::get_br_ptr () const
|
||||
{
|
||||
return (&_br_lut [0]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
const typename FFTReal <DT>::DataType * FFTReal <DT>::get_trigo_ptr (int level) const
|
||||
{
|
||||
assert (level >= 3);
|
||||
|
||||
return (&_trigo_lut [get_trigo_level_index (level)]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
long FFTReal <DT>::get_trigo_level_index (int level) const
|
||||
{
|
||||
assert (level >= 3);
|
||||
|
||||
return ((1L << (level - 1)) - 4);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Transform in several passes
|
||||
template <class DT>
|
||||
void FFTReal <DT>::compute_fft_general (DataType f [], const DataType x []) const
|
||||
{
|
||||
assert (f != 0);
|
||||
assert (f != use_buffer ());
|
||||
assert (x != 0);
|
||||
assert (x != use_buffer ());
|
||||
assert (x != f);
|
||||
|
||||
DataType * sf;
|
||||
DataType * df;
|
||||
|
||||
if ((_nbr_bits & 1) != 0)
|
||||
{
|
||||
df = use_buffer ();
|
||||
sf = f;
|
||||
}
|
||||
else
|
||||
{
|
||||
df = f;
|
||||
sf = use_buffer ();
|
||||
}
|
||||
|
||||
compute_direct_pass_1_2 (df, x);
|
||||
compute_direct_pass_3 (sf, df);
|
||||
|
||||
for (int pass = 3; pass < _nbr_bits; ++ pass)
|
||||
{
|
||||
compute_direct_pass_n (df, sf, pass);
|
||||
|
||||
DataType * const temp_ptr = df;
|
||||
df = sf;
|
||||
sf = temp_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
void FFTReal <DT>::compute_direct_pass_1_2 (DataType df [], const DataType x []) const
|
||||
{
|
||||
assert (df != 0);
|
||||
assert (x != 0);
|
||||
assert (df != x);
|
||||
|
||||
const long * const bit_rev_lut_ptr = get_br_ptr ();
|
||||
long coef_index = 0;
|
||||
do
|
||||
{
|
||||
const long rev_index_0 = bit_rev_lut_ptr [coef_index];
|
||||
const long rev_index_1 = bit_rev_lut_ptr [coef_index + 1];
|
||||
const long rev_index_2 = bit_rev_lut_ptr [coef_index + 2];
|
||||
const long rev_index_3 = bit_rev_lut_ptr [coef_index + 3];
|
||||
|
||||
DataType * const df2 = df + coef_index;
|
||||
df2 [1] = x [rev_index_0] - x [rev_index_1];
|
||||
df2 [3] = x [rev_index_2] - x [rev_index_3];
|
||||
|
||||
const DataType sf_0 = x [rev_index_0] + x [rev_index_1];
|
||||
const DataType sf_2 = x [rev_index_2] + x [rev_index_3];
|
||||
|
||||
df2 [0] = sf_0 + sf_2;
|
||||
df2 [2] = sf_0 - sf_2;
|
||||
|
||||
coef_index += 4;
|
||||
}
|
||||
while (coef_index < _length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
void FFTReal <DT>::compute_direct_pass_3 (DataType df [], const DataType sf []) const
|
||||
{
|
||||
assert (df != 0);
|
||||
assert (sf != 0);
|
||||
assert (df != sf);
|
||||
|
||||
const DataType sqrt2_2 = DataType (SQRT2 * 0.5);
|
||||
long coef_index = 0;
|
||||
do
|
||||
{
|
||||
DataType v;
|
||||
|
||||
df [coef_index] = sf [coef_index] + sf [coef_index + 4];
|
||||
df [coef_index + 4] = sf [coef_index] - sf [coef_index + 4];
|
||||
df [coef_index + 2] = sf [coef_index + 2];
|
||||
df [coef_index + 6] = sf [coef_index + 6];
|
||||
|
||||
v = (sf [coef_index + 5] - sf [coef_index + 7]) * sqrt2_2;
|
||||
df [coef_index + 1] = sf [coef_index + 1] + v;
|
||||
df [coef_index + 3] = sf [coef_index + 1] - v;
|
||||
|
||||
v = (sf [coef_index + 5] + sf [coef_index + 7]) * sqrt2_2;
|
||||
df [coef_index + 5] = v + sf [coef_index + 3];
|
||||
df [coef_index + 7] = v - sf [coef_index + 3];
|
||||
|
||||
coef_index += 8;
|
||||
}
|
||||
while (coef_index < _length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
void FFTReal <DT>::compute_direct_pass_n (DataType df [], const DataType sf [], int pass) const
|
||||
{
|
||||
assert (df != 0);
|
||||
assert (sf != 0);
|
||||
assert (df != sf);
|
||||
assert (pass >= 3);
|
||||
assert (pass < _nbr_bits);
|
||||
|
||||
if (pass <= TRIGO_BD_LIMIT)
|
||||
{
|
||||
compute_direct_pass_n_lut (df, sf, pass);
|
||||
}
|
||||
else
|
||||
{
|
||||
compute_direct_pass_n_osc (df, sf, pass);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
void FFTReal <DT>::compute_direct_pass_n_lut (DataType df [], const DataType sf [], int pass) const
|
||||
{
|
||||
assert (df != 0);
|
||||
assert (sf != 0);
|
||||
assert (df != sf);
|
||||
assert (pass >= 3);
|
||||
assert (pass < _nbr_bits);
|
||||
|
||||
const long nbr_coef = 1 << pass;
|
||||
const long h_nbr_coef = nbr_coef >> 1;
|
||||
const long d_nbr_coef = nbr_coef << 1;
|
||||
long coef_index = 0;
|
||||
const DataType * const cos_ptr = get_trigo_ptr (pass);
|
||||
do
|
||||
{
|
||||
const DataType * const sf1r = sf + coef_index;
|
||||
const DataType * const sf2r = sf1r + nbr_coef;
|
||||
DataType * const dfr = df + coef_index;
|
||||
DataType * const dfi = dfr + nbr_coef;
|
||||
|
||||
// Extreme coefficients are always real
|
||||
dfr [0] = sf1r [0] + sf2r [0];
|
||||
dfi [0] = sf1r [0] - sf2r [0]; // dfr [nbr_coef] =
|
||||
dfr [h_nbr_coef] = sf1r [h_nbr_coef];
|
||||
dfi [h_nbr_coef] = sf2r [h_nbr_coef];
|
||||
|
||||
// Others are conjugate complex numbers
|
||||
const DataType * const sf1i = sf1r + h_nbr_coef;
|
||||
const DataType * const sf2i = sf1i + nbr_coef;
|
||||
for (long i = 1; i < h_nbr_coef; ++ i)
|
||||
{
|
||||
const DataType c = cos_ptr [i]; // cos (i*PI/nbr_coef);
|
||||
const DataType s = cos_ptr [h_nbr_coef - i]; // sin (i*PI/nbr_coef);
|
||||
DataType v;
|
||||
|
||||
v = sf2r [i] * c - sf2i [i] * s;
|
||||
dfr [i] = sf1r [i] + v;
|
||||
dfi [-i] = sf1r [i] - v; // dfr [nbr_coef - i] =
|
||||
|
||||
v = sf2r [i] * s + sf2i [i] * c;
|
||||
dfi [i] = v + sf1i [i];
|
||||
dfi [nbr_coef - i] = v - sf1i [i];
|
||||
}
|
||||
|
||||
coef_index += d_nbr_coef;
|
||||
}
|
||||
while (coef_index < _length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
void FFTReal <DT>::compute_direct_pass_n_osc (DataType df [], const DataType sf [], int pass) const
|
||||
{
|
||||
assert (df != 0);
|
||||
assert (sf != 0);
|
||||
assert (df != sf);
|
||||
assert (pass > TRIGO_BD_LIMIT);
|
||||
assert (pass < _nbr_bits);
|
||||
|
||||
const long nbr_coef = 1 << pass;
|
||||
const long h_nbr_coef = nbr_coef >> 1;
|
||||
const long d_nbr_coef = nbr_coef << 1;
|
||||
long coef_index = 0;
|
||||
OscType & osc = _trigo_osc [pass - (TRIGO_BD_LIMIT + 1)];
|
||||
do
|
||||
{
|
||||
const DataType * const sf1r = sf + coef_index;
|
||||
const DataType * const sf2r = sf1r + nbr_coef;
|
||||
DataType * const dfr = df + coef_index;
|
||||
DataType * const dfi = dfr + nbr_coef;
|
||||
|
||||
osc.clear_buffers ();
|
||||
|
||||
// Extreme coefficients are always real
|
||||
dfr [0] = sf1r [0] + sf2r [0];
|
||||
dfi [0] = sf1r [0] - sf2r [0]; // dfr [nbr_coef] =
|
||||
dfr [h_nbr_coef] = sf1r [h_nbr_coef];
|
||||
dfi [h_nbr_coef] = sf2r [h_nbr_coef];
|
||||
|
||||
// Others are conjugate complex numbers
|
||||
const DataType * const sf1i = sf1r + h_nbr_coef;
|
||||
const DataType * const sf2i = sf1i + nbr_coef;
|
||||
for (long i = 1; i < h_nbr_coef; ++ i)
|
||||
{
|
||||
osc.step ();
|
||||
const DataType c = osc.get_cos ();
|
||||
const DataType s = osc.get_sin ();
|
||||
DataType v;
|
||||
|
||||
v = sf2r [i] * c - sf2i [i] * s;
|
||||
dfr [i] = sf1r [i] + v;
|
||||
dfi [-i] = sf1r [i] - v; // dfr [nbr_coef - i] =
|
||||
|
||||
v = sf2r [i] * s + sf2i [i] * c;
|
||||
dfi [i] = v + sf1i [i];
|
||||
dfi [nbr_coef - i] = v - sf1i [i];
|
||||
}
|
||||
|
||||
coef_index += d_nbr_coef;
|
||||
}
|
||||
while (coef_index < _length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Transform in several pass
|
||||
template <class DT>
|
||||
void FFTReal <DT>::compute_ifft_general (const DataType f [], DataType x []) const
|
||||
{
|
||||
assert (f != 0);
|
||||
assert (f != use_buffer ());
|
||||
assert (x != 0);
|
||||
assert (x != use_buffer ());
|
||||
assert (x != f);
|
||||
|
||||
DataType * sf = const_cast <DataType *> (f);
|
||||
DataType * df;
|
||||
DataType * df_temp;
|
||||
|
||||
if (_nbr_bits & 1)
|
||||
{
|
||||
df = use_buffer ();
|
||||
df_temp = x;
|
||||
}
|
||||
else
|
||||
{
|
||||
df = x;
|
||||
df_temp = use_buffer ();
|
||||
}
|
||||
|
||||
for (int pass = _nbr_bits - 1; pass >= 3; -- pass)
|
||||
{
|
||||
compute_inverse_pass_n (df, sf, pass);
|
||||
|
||||
if (pass < _nbr_bits - 1)
|
||||
{
|
||||
DataType * const temp_ptr = df;
|
||||
df = sf;
|
||||
sf = temp_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
sf = df;
|
||||
df = df_temp;
|
||||
}
|
||||
}
|
||||
|
||||
compute_inverse_pass_3 (df, sf);
|
||||
compute_inverse_pass_1_2 (x, df);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
void FFTReal <DT>::compute_inverse_pass_n (DataType df [], const DataType sf [], int pass) const
|
||||
{
|
||||
assert (df != 0);
|
||||
assert (sf != 0);
|
||||
assert (df != sf);
|
||||
assert (pass >= 3);
|
||||
assert (pass < _nbr_bits);
|
||||
|
||||
if (pass <= TRIGO_BD_LIMIT)
|
||||
{
|
||||
compute_inverse_pass_n_lut (df, sf, pass);
|
||||
}
|
||||
else
|
||||
{
|
||||
compute_inverse_pass_n_osc (df, sf, pass);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
void FFTReal <DT>::compute_inverse_pass_n_lut (DataType df [], const DataType sf [], int pass) const
|
||||
{
|
||||
assert (df != 0);
|
||||
assert (sf != 0);
|
||||
assert (df != sf);
|
||||
assert (pass >= 3);
|
||||
assert (pass < _nbr_bits);
|
||||
|
||||
const long nbr_coef = 1 << pass;
|
||||
const long h_nbr_coef = nbr_coef >> 1;
|
||||
const long d_nbr_coef = nbr_coef << 1;
|
||||
long coef_index = 0;
|
||||
const DataType * const cos_ptr = get_trigo_ptr (pass);
|
||||
do
|
||||
{
|
||||
const DataType * const sfr = sf + coef_index;
|
||||
const DataType * const sfi = sfr + nbr_coef;
|
||||
DataType * const df1r = df + coef_index;
|
||||
DataType * const df2r = df1r + nbr_coef;
|
||||
|
||||
// Extreme coefficients are always real
|
||||
df1r [0] = sfr [0] + sfi [0]; // + sfr [nbr_coef]
|
||||
df2r [0] = sfr [0] - sfi [0]; // - sfr [nbr_coef]
|
||||
df1r [h_nbr_coef] = sfr [h_nbr_coef] * 2;
|
||||
df2r [h_nbr_coef] = sfi [h_nbr_coef] * 2;
|
||||
|
||||
// Others are conjugate complex numbers
|
||||
DataType * const df1i = df1r + h_nbr_coef;
|
||||
DataType * const df2i = df1i + nbr_coef;
|
||||
for (long i = 1; i < h_nbr_coef; ++ i)
|
||||
{
|
||||
df1r [i] = sfr [i] + sfi [-i]; // + sfr [nbr_coef - i]
|
||||
df1i [i] = sfi [i] - sfi [nbr_coef - i];
|
||||
|
||||
const DataType c = cos_ptr [i]; // cos (i*PI/nbr_coef);
|
||||
const DataType s = cos_ptr [h_nbr_coef - i]; // sin (i*PI/nbr_coef);
|
||||
const DataType vr = sfr [i] - sfi [-i]; // - sfr [nbr_coef - i]
|
||||
const DataType vi = sfi [i] + sfi [nbr_coef - i];
|
||||
|
||||
df2r [i] = vr * c + vi * s;
|
||||
df2i [i] = vi * c - vr * s;
|
||||
}
|
||||
|
||||
coef_index += d_nbr_coef;
|
||||
}
|
||||
while (coef_index < _length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
void FFTReal <DT>::compute_inverse_pass_n_osc (DataType df [], const DataType sf [], int pass) const
|
||||
{
|
||||
assert (df != 0);
|
||||
assert (sf != 0);
|
||||
assert (df != sf);
|
||||
assert (pass > TRIGO_BD_LIMIT);
|
||||
assert (pass < _nbr_bits);
|
||||
|
||||
const long nbr_coef = 1 << pass;
|
||||
const long h_nbr_coef = nbr_coef >> 1;
|
||||
const long d_nbr_coef = nbr_coef << 1;
|
||||
long coef_index = 0;
|
||||
OscType & osc = _trigo_osc [pass - (TRIGO_BD_LIMIT + 1)];
|
||||
do
|
||||
{
|
||||
const DataType * const sfr = sf + coef_index;
|
||||
const DataType * const sfi = sfr + nbr_coef;
|
||||
DataType * const df1r = df + coef_index;
|
||||
DataType * const df2r = df1r + nbr_coef;
|
||||
|
||||
osc.clear_buffers ();
|
||||
|
||||
// Extreme coefficients are always real
|
||||
df1r [0] = sfr [0] + sfi [0]; // + sfr [nbr_coef]
|
||||
df2r [0] = sfr [0] - sfi [0]; // - sfr [nbr_coef]
|
||||
df1r [h_nbr_coef] = sfr [h_nbr_coef] * 2;
|
||||
df2r [h_nbr_coef] = sfi [h_nbr_coef] * 2;
|
||||
|
||||
// Others are conjugate complex numbers
|
||||
DataType * const df1i = df1r + h_nbr_coef;
|
||||
DataType * const df2i = df1i + nbr_coef;
|
||||
for (long i = 1; i < h_nbr_coef; ++ i)
|
||||
{
|
||||
df1r [i] = sfr [i] + sfi [-i]; // + sfr [nbr_coef - i]
|
||||
df1i [i] = sfi [i] - sfi [nbr_coef - i];
|
||||
|
||||
osc.step ();
|
||||
const DataType c = osc.get_cos ();
|
||||
const DataType s = osc.get_sin ();
|
||||
const DataType vr = sfr [i] - sfi [-i]; // - sfr [nbr_coef - i]
|
||||
const DataType vi = sfi [i] + sfi [nbr_coef - i];
|
||||
|
||||
df2r [i] = vr * c + vi * s;
|
||||
df2i [i] = vi * c - vr * s;
|
||||
}
|
||||
|
||||
coef_index += d_nbr_coef;
|
||||
}
|
||||
while (coef_index < _length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
void FFTReal <DT>::compute_inverse_pass_3 (DataType df [], const DataType sf []) const
|
||||
{
|
||||
assert (df != 0);
|
||||
assert (sf != 0);
|
||||
assert (df != sf);
|
||||
|
||||
const DataType sqrt2_2 = DataType (SQRT2 * 0.5);
|
||||
long coef_index = 0;
|
||||
do
|
||||
{
|
||||
df [coef_index] = sf [coef_index] + sf [coef_index + 4];
|
||||
df [coef_index + 4] = sf [coef_index] - sf [coef_index + 4];
|
||||
df [coef_index + 2] = sf [coef_index + 2] * 2;
|
||||
df [coef_index + 6] = sf [coef_index + 6] * 2;
|
||||
|
||||
df [coef_index + 1] = sf [coef_index + 1] + sf [coef_index + 3];
|
||||
df [coef_index + 3] = sf [coef_index + 5] - sf [coef_index + 7];
|
||||
|
||||
const DataType vr = sf [coef_index + 1] - sf [coef_index + 3];
|
||||
const DataType vi = sf [coef_index + 5] + sf [coef_index + 7];
|
||||
|
||||
df [coef_index + 5] = (vr + vi) * sqrt2_2;
|
||||
df [coef_index + 7] = (vi - vr) * sqrt2_2;
|
||||
|
||||
coef_index += 8;
|
||||
}
|
||||
while (coef_index < _length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
void FFTReal <DT>::compute_inverse_pass_1_2 (DataType x [], const DataType sf []) const
|
||||
{
|
||||
assert (x != 0);
|
||||
assert (sf != 0);
|
||||
assert (x != sf);
|
||||
|
||||
const long * bit_rev_lut_ptr = get_br_ptr ();
|
||||
const DataType * sf2 = sf;
|
||||
long coef_index = 0;
|
||||
do
|
||||
{
|
||||
{
|
||||
const DataType b_0 = sf2 [0] + sf2 [2];
|
||||
const DataType b_2 = sf2 [0] - sf2 [2];
|
||||
const DataType b_1 = sf2 [1] * 2;
|
||||
const DataType b_3 = sf2 [3] * 2;
|
||||
|
||||
x [bit_rev_lut_ptr [0]] = b_0 + b_1;
|
||||
x [bit_rev_lut_ptr [1]] = b_0 - b_1;
|
||||
x [bit_rev_lut_ptr [2]] = b_2 + b_3;
|
||||
x [bit_rev_lut_ptr [3]] = b_2 - b_3;
|
||||
}
|
||||
{
|
||||
const DataType b_0 = sf2 [4] + sf2 [6];
|
||||
const DataType b_2 = sf2 [4] - sf2 [6];
|
||||
const DataType b_1 = sf2 [5] * 2;
|
||||
const DataType b_3 = sf2 [7] * 2;
|
||||
|
||||
x [bit_rev_lut_ptr [4]] = b_0 + b_1;
|
||||
x [bit_rev_lut_ptr [5]] = b_0 - b_1;
|
||||
x [bit_rev_lut_ptr [6]] = b_2 + b_3;
|
||||
x [bit_rev_lut_ptr [7]] = b_2 - b_3;
|
||||
}
|
||||
|
||||
sf2 += 8;
|
||||
coef_index += 8;
|
||||
bit_rev_lut_ptr += 8;
|
||||
}
|
||||
while (coef_index < _length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // FFTReal_CODEHEADER_INCLUDED
|
||||
|
||||
#undef FFTReal_CURRENT_CODEHEADER
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
130
examples/multimedia/spectrum/3rdparty/fftreal/FFTRealFixLen.h
vendored
Normal file
130
examples/multimedia/spectrum/3rdparty/fftreal/FFTRealFixLen.h
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
/*****************************************************************************
|
||||
|
||||
FFTRealFixLen.h
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if ! defined (FFTRealFixLen_HEADER_INCLUDED)
|
||||
#define FFTRealFixLen_HEADER_INCLUDED
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma once
|
||||
#pragma warning (4 : 4250) // "Inherits via dominance."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include "Array.h"
|
||||
#include "DynArray.h"
|
||||
#include "FFTRealFixLenParam.h"
|
||||
#include "OscSinCos.h"
|
||||
|
||||
|
||||
|
||||
template <int LL2>
|
||||
class FFTRealFixLen
|
||||
{
|
||||
typedef int CompileTimeCheck1 [(LL2 >= 0) ? 1 : -1];
|
||||
typedef int CompileTimeCheck2 [(LL2 <= 30) ? 1 : -1];
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
public:
|
||||
|
||||
typedef FFTRealFixLenParam::DataType DataType;
|
||||
typedef OscSinCos <DataType> OscType;
|
||||
|
||||
enum { FFT_LEN_L2 = LL2 };
|
||||
enum { FFT_LEN = 1 << FFT_LEN_L2 };
|
||||
|
||||
FFTRealFixLen ();
|
||||
|
||||
inline long get_length () const;
|
||||
void do_fft (DataType f [], const DataType x []);
|
||||
void do_ifft (const DataType f [], DataType x []);
|
||||
void rescale (DataType x []) const;
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
enum { TRIGO_BD_LIMIT = FFTRealFixLenParam::TRIGO_BD_LIMIT };
|
||||
|
||||
enum { BR_ARR_SIZE_L2 = ((FFT_LEN_L2 - 3) < 0) ? 0 : (FFT_LEN_L2 - 2) };
|
||||
enum { BR_ARR_SIZE = 1 << BR_ARR_SIZE_L2 };
|
||||
|
||||
enum { TRIGO_BD = ((FFT_LEN_L2 - TRIGO_BD_LIMIT) < 0)
|
||||
? (int)FFT_LEN_L2
|
||||
: (int)TRIGO_BD_LIMIT };
|
||||
enum { TRIGO_TABLE_ARR_SIZE_L2 = (LL2 < 4) ? 0 : (TRIGO_BD - 2) };
|
||||
enum { TRIGO_TABLE_ARR_SIZE = 1 << TRIGO_TABLE_ARR_SIZE_L2 };
|
||||
|
||||
enum { NBR_TRIGO_OSC = FFT_LEN_L2 - TRIGO_BD };
|
||||
enum { TRIGO_OSC_ARR_SIZE = (NBR_TRIGO_OSC > 0) ? NBR_TRIGO_OSC : 1 };
|
||||
|
||||
void build_br_lut ();
|
||||
void build_trigo_lut ();
|
||||
void build_trigo_osc ();
|
||||
|
||||
DynArray <DataType>
|
||||
_buffer;
|
||||
DynArray <long>
|
||||
_br_data;
|
||||
DynArray <DataType>
|
||||
_trigo_data;
|
||||
Array <OscType, TRIGO_OSC_ARR_SIZE>
|
||||
_trigo_osc;
|
||||
|
||||
|
||||
|
||||
/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
FFTRealFixLen (const FFTRealFixLen &other);
|
||||
FFTRealFixLen& operator = (const FFTRealFixLen &other);
|
||||
bool operator == (const FFTRealFixLen &other);
|
||||
bool operator != (const FFTRealFixLen &other);
|
||||
|
||||
}; // class FFTRealFixLen
|
||||
|
||||
|
||||
|
||||
#include "FFTRealFixLen.hpp"
|
||||
|
||||
|
||||
|
||||
#endif // FFTRealFixLen_HEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
322
examples/multimedia/spectrum/3rdparty/fftreal/FFTRealFixLen.hpp
vendored
Normal file
322
examples/multimedia/spectrum/3rdparty/fftreal/FFTRealFixLen.hpp
vendored
Normal file
@@ -0,0 +1,322 @@
|
||||
/*****************************************************************************
|
||||
|
||||
FFTRealFixLen.hpp
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if defined (FFTRealFixLen_CURRENT_CODEHEADER)
|
||||
#error Recursive inclusion of FFTRealFixLen code header.
|
||||
#endif
|
||||
#define FFTRealFixLen_CURRENT_CODEHEADER
|
||||
|
||||
#if ! defined (FFTRealFixLen_CODEHEADER_INCLUDED)
|
||||
#define FFTRealFixLen_CODEHEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include "def.h"
|
||||
#include "FFTRealPassDirect.h"
|
||||
#include "FFTRealPassInverse.h"
|
||||
#include "FFTRealSelect.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
|
||||
namespace std { }
|
||||
|
||||
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
template <int LL2>
|
||||
FFTRealFixLen <LL2>::FFTRealFixLen ()
|
||||
: _buffer (FFT_LEN)
|
||||
, _br_data (BR_ARR_SIZE)
|
||||
, _trigo_data (TRIGO_TABLE_ARR_SIZE)
|
||||
, _trigo_osc ()
|
||||
{
|
||||
build_br_lut ();
|
||||
build_trigo_lut ();
|
||||
build_trigo_osc ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <int LL2>
|
||||
long FFTRealFixLen <LL2>::get_length () const
|
||||
{
|
||||
return (FFT_LEN);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// General case
|
||||
template <int LL2>
|
||||
void FFTRealFixLen <LL2>::do_fft (DataType f [], const DataType x [])
|
||||
{
|
||||
assert (f != 0);
|
||||
assert (x != 0);
|
||||
assert (x != f);
|
||||
assert (FFT_LEN_L2 >= 3);
|
||||
|
||||
// Do the transform in several passes
|
||||
const DataType * cos_ptr = &_trigo_data [0];
|
||||
const long * br_ptr = &_br_data [0];
|
||||
|
||||
FFTRealPassDirect <FFT_LEN_L2 - 1>::process (
|
||||
FFT_LEN,
|
||||
f,
|
||||
&_buffer [0],
|
||||
x,
|
||||
cos_ptr,
|
||||
TRIGO_TABLE_ARR_SIZE,
|
||||
br_ptr,
|
||||
&_trigo_osc [0]
|
||||
);
|
||||
}
|
||||
|
||||
// 4-point FFT
|
||||
template <>
|
||||
void FFTRealFixLen <2>::do_fft (DataType f [], const DataType x [])
|
||||
{
|
||||
assert (f != 0);
|
||||
assert (x != 0);
|
||||
assert (x != f);
|
||||
|
||||
f [1] = x [0] - x [2];
|
||||
f [3] = x [1] - x [3];
|
||||
|
||||
const DataType b_0 = x [0] + x [2];
|
||||
const DataType b_2 = x [1] + x [3];
|
||||
|
||||
f [0] = b_0 + b_2;
|
||||
f [2] = b_0 - b_2;
|
||||
}
|
||||
|
||||
// 2-point FFT
|
||||
template <>
|
||||
void FFTRealFixLen <1>::do_fft (DataType f [], const DataType x [])
|
||||
{
|
||||
assert (f != 0);
|
||||
assert (x != 0);
|
||||
assert (x != f);
|
||||
|
||||
f [0] = x [0] + x [1];
|
||||
f [1] = x [0] - x [1];
|
||||
}
|
||||
|
||||
// 1-point FFT
|
||||
template <>
|
||||
void FFTRealFixLen <0>::do_fft (DataType f [], const DataType x [])
|
||||
{
|
||||
assert (f != 0);
|
||||
assert (x != 0);
|
||||
|
||||
f [0] = x [0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
// General case
|
||||
template <int LL2>
|
||||
void FFTRealFixLen <LL2>::do_ifft (const DataType f [], DataType x [])
|
||||
{
|
||||
assert (f != 0);
|
||||
assert (x != 0);
|
||||
assert (x != f);
|
||||
assert (FFT_LEN_L2 >= 3);
|
||||
|
||||
// Do the transform in several passes
|
||||
DataType * s_ptr =
|
||||
FFTRealSelect <FFT_LEN_L2 & 1>::sel_bin (&_buffer [0], x);
|
||||
DataType * d_ptr =
|
||||
FFTRealSelect <FFT_LEN_L2 & 1>::sel_bin (x, &_buffer [0]);
|
||||
const DataType * cos_ptr = &_trigo_data [0];
|
||||
const long * br_ptr = &_br_data [0];
|
||||
|
||||
FFTRealPassInverse <FFT_LEN_L2 - 1>::process (
|
||||
FFT_LEN,
|
||||
d_ptr,
|
||||
s_ptr,
|
||||
f,
|
||||
cos_ptr,
|
||||
TRIGO_TABLE_ARR_SIZE,
|
||||
br_ptr,
|
||||
&_trigo_osc [0]
|
||||
);
|
||||
}
|
||||
|
||||
// 4-point IFFT
|
||||
template <>
|
||||
void FFTRealFixLen <2>::do_ifft (const DataType f [], DataType x [])
|
||||
{
|
||||
assert (f != 0);
|
||||
assert (x != 0);
|
||||
assert (x != f);
|
||||
|
||||
const DataType b_0 = f [0] + f [2];
|
||||
const DataType b_2 = f [0] - f [2];
|
||||
|
||||
x [0] = b_0 + f [1] * 2;
|
||||
x [2] = b_0 - f [1] * 2;
|
||||
x [1] = b_2 + f [3] * 2;
|
||||
x [3] = b_2 - f [3] * 2;
|
||||
}
|
||||
|
||||
// 2-point IFFT
|
||||
template <>
|
||||
void FFTRealFixLen <1>::do_ifft (const DataType f [], DataType x [])
|
||||
{
|
||||
assert (f != 0);
|
||||
assert (x != 0);
|
||||
assert (x != f);
|
||||
|
||||
x [0] = f [0] + f [1];
|
||||
x [1] = f [0] - f [1];
|
||||
}
|
||||
|
||||
// 1-point IFFT
|
||||
template <>
|
||||
void FFTRealFixLen <0>::do_ifft (const DataType f [], DataType x [])
|
||||
{
|
||||
assert (f != 0);
|
||||
assert (x != 0);
|
||||
assert (x != f);
|
||||
|
||||
x [0] = f [0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template <int LL2>
|
||||
void FFTRealFixLen <LL2>::rescale (DataType x []) const
|
||||
{
|
||||
assert (x != 0);
|
||||
|
||||
const DataType mul = DataType (1.0 / FFT_LEN);
|
||||
|
||||
if (FFT_LEN < 4)
|
||||
{
|
||||
long i = FFT_LEN - 1;
|
||||
do
|
||||
{
|
||||
x [i] *= mul;
|
||||
--i;
|
||||
}
|
||||
while (i >= 0);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
assert ((FFT_LEN & 3) == 0);
|
||||
|
||||
// Could be optimized with SIMD instruction sets (needs alignment check)
|
||||
long i = FFT_LEN - 4;
|
||||
do
|
||||
{
|
||||
x [i + 0] *= mul;
|
||||
x [i + 1] *= mul;
|
||||
x [i + 2] *= mul;
|
||||
x [i + 3] *= mul;
|
||||
i -= 4;
|
||||
}
|
||||
while (i >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
template <int LL2>
|
||||
void FFTRealFixLen <LL2>::build_br_lut ()
|
||||
{
|
||||
_br_data [0] = 0;
|
||||
for (long cnt = 1; cnt < BR_ARR_SIZE; ++cnt)
|
||||
{
|
||||
long index = cnt << 2;
|
||||
long br_index = 0;
|
||||
|
||||
int bit_cnt = FFT_LEN_L2;
|
||||
do
|
||||
{
|
||||
br_index <<= 1;
|
||||
br_index += (index & 1);
|
||||
index >>= 1;
|
||||
|
||||
-- bit_cnt;
|
||||
}
|
||||
while (bit_cnt > 0);
|
||||
|
||||
_br_data [cnt] = br_index;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <int LL2>
|
||||
void FFTRealFixLen <LL2>::build_trigo_lut ()
|
||||
{
|
||||
const double mul = (0.5 * PI) / TRIGO_TABLE_ARR_SIZE;
|
||||
for (long i = 0; i < TRIGO_TABLE_ARR_SIZE; ++ i)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
_trigo_data [i] = DataType (cos (i * mul));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <int LL2>
|
||||
void FFTRealFixLen <LL2>::build_trigo_osc ()
|
||||
{
|
||||
for (int i = 0; i < NBR_TRIGO_OSC; ++i)
|
||||
{
|
||||
OscType & osc = _trigo_osc [i];
|
||||
|
||||
const long len = static_cast <long> (TRIGO_TABLE_ARR_SIZE) << (i + 1);
|
||||
const double mul = (0.5 * PI) / len;
|
||||
osc.set_step (mul);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // FFTRealFixLen_CODEHEADER_INCLUDED
|
||||
|
||||
#undef FFTRealFixLen_CURRENT_CODEHEADER
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
93
examples/multimedia/spectrum/3rdparty/fftreal/FFTRealFixLenParam.h
vendored
Normal file
93
examples/multimedia/spectrum/3rdparty/fftreal/FFTRealFixLenParam.h
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
/*****************************************************************************
|
||||
|
||||
FFTRealFixLenParam.h
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if ! defined (FFTRealFixLenParam_HEADER_INCLUDED)
|
||||
#define FFTRealFixLenParam_HEADER_INCLUDED
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma once
|
||||
#pragma warning (4 : 4250) // "Inherits via dominance."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
class FFTRealFixLenParam
|
||||
{
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
public:
|
||||
|
||||
// Over this bit depth, we use direct calculation for sin/cos
|
||||
enum { TRIGO_BD_LIMIT = 12 };
|
||||
|
||||
typedef float DataType;
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
#if 0 // To avoid GCC warning:
|
||||
// All member functions in class 'FFTRealFixLenParam' are private
|
||||
FFTRealFixLenParam ();
|
||||
~FFTRealFixLenParam ();
|
||||
FFTRealFixLenParam (const FFTRealFixLenParam &other);
|
||||
FFTRealFixLenParam &
|
||||
operator = (const FFTRealFixLenParam &other);
|
||||
bool operator == (const FFTRealFixLenParam &other);
|
||||
bool operator != (const FFTRealFixLenParam &other);
|
||||
#endif
|
||||
|
||||
}; // class FFTRealFixLenParam
|
||||
|
||||
|
||||
|
||||
//#include "FFTRealFixLenParam.hpp"
|
||||
|
||||
|
||||
|
||||
#endif // FFTRealFixLenParam_HEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
96
examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassDirect.h
vendored
Normal file
96
examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassDirect.h
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
/*****************************************************************************
|
||||
|
||||
FFTRealPassDirect.h
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if ! defined (FFTRealPassDirect_HEADER_INCLUDED)
|
||||
#define FFTRealPassDirect_HEADER_INCLUDED
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma once
|
||||
#pragma warning (4 : 4250) // "Inherits via dominance."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include "def.h"
|
||||
#include "FFTRealFixLenParam.h"
|
||||
#include "OscSinCos.h"
|
||||
|
||||
|
||||
|
||||
template <int PASS>
|
||||
class FFTRealPassDirect
|
||||
{
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
public:
|
||||
|
||||
typedef FFTRealFixLenParam::DataType DataType;
|
||||
typedef OscSinCos <DataType> OscType;
|
||||
|
||||
FORCEINLINE static void
|
||||
process (long len, DataType dest_ptr [], DataType src_ptr [], const DataType x_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list []);
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
FFTRealPassDirect ();
|
||||
~FFTRealPassDirect ();
|
||||
FFTRealPassDirect (const FFTRealPassDirect &other);
|
||||
FFTRealPassDirect &
|
||||
operator = (const FFTRealPassDirect &other);
|
||||
bool operator == (const FFTRealPassDirect &other);
|
||||
bool operator != (const FFTRealPassDirect &other);
|
||||
|
||||
}; // class FFTRealPassDirect
|
||||
|
||||
|
||||
|
||||
#include "FFTRealPassDirect.hpp"
|
||||
|
||||
|
||||
|
||||
#endif // FFTRealPassDirect_HEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
204
examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassDirect.hpp
vendored
Normal file
204
examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassDirect.hpp
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
/*****************************************************************************
|
||||
|
||||
FFTRealPassDirect.hpp
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if defined (FFTRealPassDirect_CURRENT_CODEHEADER)
|
||||
#error Recursive inclusion of FFTRealPassDirect code header.
|
||||
#endif
|
||||
#define FFTRealPassDirect_CURRENT_CODEHEADER
|
||||
|
||||
#if ! defined (FFTRealPassDirect_CODEHEADER_INCLUDED)
|
||||
#define FFTRealPassDirect_CODEHEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include "FFTRealUseTrigo.h"
|
||||
|
||||
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
template <>
|
||||
void FFTRealPassDirect <1>::process (long len, DataType dest_ptr [], DataType src_ptr [], const DataType x_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list [])
|
||||
{
|
||||
// First and second pass at once
|
||||
const long qlen = len >> 2;
|
||||
|
||||
long coef_index = 0;
|
||||
do
|
||||
{
|
||||
// To do: unroll the loop (2x).
|
||||
const long ri_0 = br_ptr [coef_index >> 2];
|
||||
const long ri_1 = ri_0 + 2 * qlen; // bit_rev_lut_ptr [coef_index + 1];
|
||||
const long ri_2 = ri_0 + 1 * qlen; // bit_rev_lut_ptr [coef_index + 2];
|
||||
const long ri_3 = ri_0 + 3 * qlen; // bit_rev_lut_ptr [coef_index + 3];
|
||||
|
||||
DataType * const df2 = dest_ptr + coef_index;
|
||||
df2 [1] = x_ptr [ri_0] - x_ptr [ri_1];
|
||||
df2 [3] = x_ptr [ri_2] - x_ptr [ri_3];
|
||||
|
||||
const DataType sf_0 = x_ptr [ri_0] + x_ptr [ri_1];
|
||||
const DataType sf_2 = x_ptr [ri_2] + x_ptr [ri_3];
|
||||
|
||||
df2 [0] = sf_0 + sf_2;
|
||||
df2 [2] = sf_0 - sf_2;
|
||||
|
||||
coef_index += 4;
|
||||
}
|
||||
while (coef_index < len);
|
||||
}
|
||||
|
||||
template <>
|
||||
void FFTRealPassDirect <2>::process (long len, DataType dest_ptr [], DataType src_ptr [], const DataType x_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list [])
|
||||
{
|
||||
// Executes "previous" passes first. Inverts source and destination buffers
|
||||
FFTRealPassDirect <1>::process (
|
||||
len,
|
||||
src_ptr,
|
||||
dest_ptr,
|
||||
x_ptr,
|
||||
cos_ptr,
|
||||
cos_len,
|
||||
br_ptr,
|
||||
osc_list
|
||||
);
|
||||
|
||||
// Third pass
|
||||
const DataType sqrt2_2 = DataType (SQRT2 * 0.5);
|
||||
|
||||
long coef_index = 0;
|
||||
do
|
||||
{
|
||||
dest_ptr [coef_index ] = src_ptr [coef_index] + src_ptr [coef_index + 4];
|
||||
dest_ptr [coef_index + 4] = src_ptr [coef_index] - src_ptr [coef_index + 4];
|
||||
dest_ptr [coef_index + 2] = src_ptr [coef_index + 2];
|
||||
dest_ptr [coef_index + 6] = src_ptr [coef_index + 6];
|
||||
|
||||
DataType v;
|
||||
|
||||
v = (src_ptr [coef_index + 5] - src_ptr [coef_index + 7]) * sqrt2_2;
|
||||
dest_ptr [coef_index + 1] = src_ptr [coef_index + 1] + v;
|
||||
dest_ptr [coef_index + 3] = src_ptr [coef_index + 1] - v;
|
||||
|
||||
v = (src_ptr [coef_index + 5] + src_ptr [coef_index + 7]) * sqrt2_2;
|
||||
dest_ptr [coef_index + 5] = v + src_ptr [coef_index + 3];
|
||||
dest_ptr [coef_index + 7] = v - src_ptr [coef_index + 3];
|
||||
|
||||
coef_index += 8;
|
||||
}
|
||||
while (coef_index < len);
|
||||
}
|
||||
|
||||
template <int PASS>
|
||||
void FFTRealPassDirect <PASS>::process (long len, DataType dest_ptr [], DataType src_ptr [], const DataType x_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list [])
|
||||
{
|
||||
// Executes "previous" passes first. Inverts source and destination buffers
|
||||
FFTRealPassDirect <PASS - 1>::process (
|
||||
len,
|
||||
src_ptr,
|
||||
dest_ptr,
|
||||
x_ptr,
|
||||
cos_ptr,
|
||||
cos_len,
|
||||
br_ptr,
|
||||
osc_list
|
||||
);
|
||||
|
||||
const long dist = 1L << (PASS - 1);
|
||||
const long c1_r = 0;
|
||||
const long c1_i = dist;
|
||||
const long c2_r = dist * 2;
|
||||
const long c2_i = dist * 3;
|
||||
const long cend = dist * 4;
|
||||
const long table_step = cos_len >> (PASS - 1);
|
||||
|
||||
enum { TRIGO_OSC = PASS - FFTRealFixLenParam::TRIGO_BD_LIMIT };
|
||||
enum { TRIGO_DIRECT = (TRIGO_OSC >= 0) ? 1 : 0 };
|
||||
|
||||
long coef_index = 0;
|
||||
do
|
||||
{
|
||||
const DataType * const sf = src_ptr + coef_index;
|
||||
DataType * const df = dest_ptr + coef_index;
|
||||
|
||||
// Extreme coefficients are always real
|
||||
df [c1_r] = sf [c1_r] + sf [c2_r];
|
||||
df [c2_r] = sf [c1_r] - sf [c2_r];
|
||||
df [c1_i] = sf [c1_i];
|
||||
df [c2_i] = sf [c2_i];
|
||||
|
||||
FFTRealUseTrigo <TRIGO_DIRECT>::prepare (osc_list [TRIGO_OSC]);
|
||||
|
||||
// Others are conjugate complex numbers
|
||||
for (long i = 1; i < dist; ++ i)
|
||||
{
|
||||
DataType c;
|
||||
DataType s;
|
||||
FFTRealUseTrigo <TRIGO_DIRECT>::iterate (
|
||||
osc_list [TRIGO_OSC],
|
||||
c,
|
||||
s,
|
||||
cos_ptr,
|
||||
i * table_step,
|
||||
(dist - i) * table_step
|
||||
);
|
||||
|
||||
const DataType sf_r_i = sf [c1_r + i];
|
||||
const DataType sf_i_i = sf [c1_i + i];
|
||||
|
||||
const DataType v1 = sf [c2_r + i] * c - sf [c2_i + i] * s;
|
||||
df [c1_r + i] = sf_r_i + v1;
|
||||
df [c2_r - i] = sf_r_i - v1;
|
||||
|
||||
const DataType v2 = sf [c2_r + i] * s + sf [c2_i + i] * c;
|
||||
df [c2_r + i] = v2 + sf_i_i;
|
||||
df [cend - i] = v2 - sf_i_i;
|
||||
}
|
||||
|
||||
coef_index += cend;
|
||||
}
|
||||
while (coef_index < len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
#endif // FFTRealPassDirect_CODEHEADER_INCLUDED
|
||||
|
||||
#undef FFTRealPassDirect_CURRENT_CODEHEADER
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
101
examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassInverse.h
vendored
Normal file
101
examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassInverse.h
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
/*****************************************************************************
|
||||
|
||||
FFTRealPassInverse.h
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if ! defined (FFTRealPassInverse_HEADER_INCLUDED)
|
||||
#define FFTRealPassInverse_HEADER_INCLUDED
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma once
|
||||
#pragma warning (4 : 4250) // "Inherits via dominance."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include "def.h"
|
||||
#include "FFTRealFixLenParam.h"
|
||||
#include "OscSinCos.h"
|
||||
|
||||
|
||||
|
||||
|
||||
template <int PASS>
|
||||
class FFTRealPassInverse
|
||||
{
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
public:
|
||||
|
||||
typedef FFTRealFixLenParam::DataType DataType;
|
||||
typedef OscSinCos <DataType> OscType;
|
||||
|
||||
FORCEINLINE static void
|
||||
process (long len, DataType dest_ptr [], DataType src_ptr [], const DataType f_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list []);
|
||||
FORCEINLINE static void
|
||||
process_rec (long len, DataType dest_ptr [], DataType src_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list []);
|
||||
FORCEINLINE static void
|
||||
process_internal (long len, DataType dest_ptr [], const DataType src_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list []);
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
FFTRealPassInverse ();
|
||||
~FFTRealPassInverse ();
|
||||
FFTRealPassInverse (const FFTRealPassInverse &other);
|
||||
FFTRealPassInverse &
|
||||
operator = (const FFTRealPassInverse &other);
|
||||
bool operator == (const FFTRealPassInverse &other);
|
||||
bool operator != (const FFTRealPassInverse &other);
|
||||
|
||||
}; // class FFTRealPassInverse
|
||||
|
||||
|
||||
|
||||
#include "FFTRealPassInverse.hpp"
|
||||
|
||||
|
||||
|
||||
#endif // FFTRealPassInverse_HEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
229
examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassInverse.hpp
vendored
Normal file
229
examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassInverse.hpp
vendored
Normal file
@@ -0,0 +1,229 @@
|
||||
/*****************************************************************************
|
||||
|
||||
FFTRealPassInverse.hpp
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if defined (FFTRealPassInverse_CURRENT_CODEHEADER)
|
||||
#error Recursive inclusion of FFTRealPassInverse code header.
|
||||
#endif
|
||||
#define FFTRealPassInverse_CURRENT_CODEHEADER
|
||||
|
||||
#if ! defined (FFTRealPassInverse_CODEHEADER_INCLUDED)
|
||||
#define FFTRealPassInverse_CODEHEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include "FFTRealUseTrigo.h"
|
||||
|
||||
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
template <int PASS>
|
||||
void FFTRealPassInverse <PASS>::process (long len, DataType dest_ptr [], DataType src_ptr [], const DataType f_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list [])
|
||||
{
|
||||
process_internal (
|
||||
len,
|
||||
dest_ptr,
|
||||
f_ptr,
|
||||
cos_ptr,
|
||||
cos_len,
|
||||
br_ptr,
|
||||
osc_list
|
||||
);
|
||||
FFTRealPassInverse <PASS - 1>::process_rec (
|
||||
len,
|
||||
src_ptr,
|
||||
dest_ptr,
|
||||
cos_ptr,
|
||||
cos_len,
|
||||
br_ptr,
|
||||
osc_list
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <int PASS>
|
||||
void FFTRealPassInverse <PASS>::process_rec (long len, DataType dest_ptr [], DataType src_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list [])
|
||||
{
|
||||
process_internal (
|
||||
len,
|
||||
dest_ptr,
|
||||
src_ptr,
|
||||
cos_ptr,
|
||||
cos_len,
|
||||
br_ptr,
|
||||
osc_list
|
||||
);
|
||||
FFTRealPassInverse <PASS - 1>::process_rec (
|
||||
len,
|
||||
src_ptr,
|
||||
dest_ptr,
|
||||
cos_ptr,
|
||||
cos_len,
|
||||
br_ptr,
|
||||
osc_list
|
||||
);
|
||||
}
|
||||
|
||||
template <>
|
||||
void FFTRealPassInverse <0>::process_rec (long len, DataType dest_ptr [], DataType src_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list [])
|
||||
{
|
||||
// Stops recursion
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <int PASS>
|
||||
void FFTRealPassInverse <PASS>::process_internal (long len, DataType dest_ptr [], const DataType src_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list [])
|
||||
{
|
||||
const long dist = 1L << (PASS - 1);
|
||||
const long c1_r = 0;
|
||||
const long c1_i = dist;
|
||||
const long c2_r = dist * 2;
|
||||
const long c2_i = dist * 3;
|
||||
const long cend = dist * 4;
|
||||
const long table_step = cos_len >> (PASS - 1);
|
||||
|
||||
enum { TRIGO_OSC = PASS - FFTRealFixLenParam::TRIGO_BD_LIMIT };
|
||||
enum { TRIGO_DIRECT = (TRIGO_OSC >= 0) ? 1 : 0 };
|
||||
|
||||
long coef_index = 0;
|
||||
do
|
||||
{
|
||||
const DataType * const sf = src_ptr + coef_index;
|
||||
DataType * const df = dest_ptr + coef_index;
|
||||
|
||||
// Extreme coefficients are always real
|
||||
df [c1_r] = sf [c1_r] + sf [c2_r];
|
||||
df [c2_r] = sf [c1_r] - sf [c2_r];
|
||||
df [c1_i] = sf [c1_i] * 2;
|
||||
df [c2_i] = sf [c2_i] * 2;
|
||||
|
||||
FFTRealUseTrigo <TRIGO_DIRECT>::prepare (osc_list [TRIGO_OSC]);
|
||||
|
||||
// Others are conjugate complex numbers
|
||||
for (long i = 1; i < dist; ++ i)
|
||||
{
|
||||
df [c1_r + i] = sf [c1_r + i] + sf [c2_r - i];
|
||||
df [c1_i + i] = sf [c2_r + i] - sf [cend - i];
|
||||
|
||||
DataType c;
|
||||
DataType s;
|
||||
FFTRealUseTrigo <TRIGO_DIRECT>::iterate (
|
||||
osc_list [TRIGO_OSC],
|
||||
c,
|
||||
s,
|
||||
cos_ptr,
|
||||
i * table_step,
|
||||
(dist - i) * table_step
|
||||
);
|
||||
|
||||
const DataType vr = sf [c1_r + i] - sf [c2_r - i];
|
||||
const DataType vi = sf [c2_r + i] + sf [cend - i];
|
||||
|
||||
df [c2_r + i] = vr * c + vi * s;
|
||||
df [c2_i + i] = vi * c - vr * s;
|
||||
}
|
||||
|
||||
coef_index += cend;
|
||||
}
|
||||
while (coef_index < len);
|
||||
}
|
||||
|
||||
template <>
|
||||
void FFTRealPassInverse <2>::process_internal (long len, DataType dest_ptr [], const DataType src_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list [])
|
||||
{
|
||||
// Antepenultimate pass
|
||||
const DataType sqrt2_2 = DataType (SQRT2 * 0.5);
|
||||
|
||||
long coef_index = 0;
|
||||
do
|
||||
{
|
||||
dest_ptr [coef_index ] = src_ptr [coef_index] + src_ptr [coef_index + 4];
|
||||
dest_ptr [coef_index + 4] = src_ptr [coef_index] - src_ptr [coef_index + 4];
|
||||
dest_ptr [coef_index + 2] = src_ptr [coef_index + 2] * 2;
|
||||
dest_ptr [coef_index + 6] = src_ptr [coef_index + 6] * 2;
|
||||
|
||||
dest_ptr [coef_index + 1] = src_ptr [coef_index + 1] + src_ptr [coef_index + 3];
|
||||
dest_ptr [coef_index + 3] = src_ptr [coef_index + 5] - src_ptr [coef_index + 7];
|
||||
|
||||
const DataType vr = src_ptr [coef_index + 1] - src_ptr [coef_index + 3];
|
||||
const DataType vi = src_ptr [coef_index + 5] + src_ptr [coef_index + 7];
|
||||
|
||||
dest_ptr [coef_index + 5] = (vr + vi) * sqrt2_2;
|
||||
dest_ptr [coef_index + 7] = (vi - vr) * sqrt2_2;
|
||||
|
||||
coef_index += 8;
|
||||
}
|
||||
while (coef_index < len);
|
||||
}
|
||||
|
||||
template <>
|
||||
void FFTRealPassInverse <1>::process_internal (long len, DataType dest_ptr [], const DataType src_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list [])
|
||||
{
|
||||
// Penultimate and last pass at once
|
||||
const long qlen = len >> 2;
|
||||
|
||||
long coef_index = 0;
|
||||
do
|
||||
{
|
||||
const long ri_0 = br_ptr [coef_index >> 2];
|
||||
|
||||
const DataType b_0 = src_ptr [coef_index ] + src_ptr [coef_index + 2];
|
||||
const DataType b_2 = src_ptr [coef_index ] - src_ptr [coef_index + 2];
|
||||
const DataType b_1 = src_ptr [coef_index + 1] * 2;
|
||||
const DataType b_3 = src_ptr [coef_index + 3] * 2;
|
||||
|
||||
dest_ptr [ri_0 ] = b_0 + b_1;
|
||||
dest_ptr [ri_0 + 2 * qlen] = b_0 - b_1;
|
||||
dest_ptr [ri_0 + 1 * qlen] = b_2 + b_3;
|
||||
dest_ptr [ri_0 + 3 * qlen] = b_2 - b_3;
|
||||
|
||||
coef_index += 4;
|
||||
}
|
||||
while (coef_index < len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
#endif // FFTRealPassInverse_CODEHEADER_INCLUDED
|
||||
|
||||
#undef FFTRealPassInverse_CURRENT_CODEHEADER
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
77
examples/multimedia/spectrum/3rdparty/fftreal/FFTRealSelect.h
vendored
Normal file
77
examples/multimedia/spectrum/3rdparty/fftreal/FFTRealSelect.h
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
/*****************************************************************************
|
||||
|
||||
FFTRealSelect.h
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if ! defined (FFTRealSelect_HEADER_INCLUDED)
|
||||
#define FFTRealSelect_HEADER_INCLUDED
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include "def.h"
|
||||
|
||||
|
||||
|
||||
template <int P>
|
||||
class FFTRealSelect
|
||||
{
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
public:
|
||||
|
||||
FORCEINLINE static float *
|
||||
sel_bin (float *e_ptr, float *o_ptr);
|
||||
|
||||
|
||||
|
||||
/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
FFTRealSelect ();
|
||||
~FFTRealSelect ();
|
||||
FFTRealSelect (const FFTRealSelect &other);
|
||||
FFTRealSelect& operator = (const FFTRealSelect &other);
|
||||
bool operator == (const FFTRealSelect &other);
|
||||
bool operator != (const FFTRealSelect &other);
|
||||
|
||||
}; // class FFTRealSelect
|
||||
|
||||
|
||||
|
||||
#include "FFTRealSelect.hpp"
|
||||
|
||||
|
||||
|
||||
#endif // FFTRealSelect_HEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
62
examples/multimedia/spectrum/3rdparty/fftreal/FFTRealSelect.hpp
vendored
Normal file
62
examples/multimedia/spectrum/3rdparty/fftreal/FFTRealSelect.hpp
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
/*****************************************************************************
|
||||
|
||||
FFTRealSelect.hpp
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if defined (FFTRealSelect_CURRENT_CODEHEADER)
|
||||
#error Recursive inclusion of FFTRealSelect code header.
|
||||
#endif
|
||||
#define FFTRealSelect_CURRENT_CODEHEADER
|
||||
|
||||
#if ! defined (FFTRealSelect_CODEHEADER_INCLUDED)
|
||||
#define FFTRealSelect_CODEHEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
template <int P>
|
||||
float * FFTRealSelect <P>::sel_bin (float *e_ptr, float *o_ptr)
|
||||
{
|
||||
return (o_ptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <>
|
||||
float * FFTRealSelect <0>::sel_bin (float *e_ptr, float *o_ptr)
|
||||
{
|
||||
return (e_ptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // FFTRealSelect_CODEHEADER_INCLUDED
|
||||
|
||||
#undef FFTRealSelect_CURRENT_CODEHEADER
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
101
examples/multimedia/spectrum/3rdparty/fftreal/FFTRealUseTrigo.h
vendored
Normal file
101
examples/multimedia/spectrum/3rdparty/fftreal/FFTRealUseTrigo.h
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
/*****************************************************************************
|
||||
|
||||
FFTRealUseTrigo.h
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
Template parameters:
|
||||
- ALGO: algorithm choice. 0 = table, other = oscillator
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if ! defined (FFTRealUseTrigo_HEADER_INCLUDED)
|
||||
#define FFTRealUseTrigo_HEADER_INCLUDED
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma once
|
||||
#pragma warning (4 : 4250) // "Inherits via dominance."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include "def.h"
|
||||
#include "FFTRealFixLenParam.h"
|
||||
#include "OscSinCos.h"
|
||||
|
||||
|
||||
|
||||
template <int ALGO>
|
||||
class FFTRealUseTrigo
|
||||
{
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
public:
|
||||
|
||||
typedef FFTRealFixLenParam::DataType DataType;
|
||||
typedef OscSinCos <DataType> OscType;
|
||||
|
||||
FORCEINLINE static void
|
||||
prepare (OscType &osc);
|
||||
FORCEINLINE static void
|
||||
iterate (OscType &osc, DataType &c, DataType &s, const DataType cos_ptr [], long index_c, long index_s);
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
FFTRealUseTrigo ();
|
||||
~FFTRealUseTrigo ();
|
||||
FFTRealUseTrigo (const FFTRealUseTrigo &other);
|
||||
FFTRealUseTrigo &
|
||||
operator = (const FFTRealUseTrigo &other);
|
||||
bool operator == (const FFTRealUseTrigo &other);
|
||||
bool operator != (const FFTRealUseTrigo &other);
|
||||
|
||||
}; // class FFTRealUseTrigo
|
||||
|
||||
|
||||
|
||||
#include "FFTRealUseTrigo.hpp"
|
||||
|
||||
|
||||
|
||||
#endif // FFTRealUseTrigo_HEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
91
examples/multimedia/spectrum/3rdparty/fftreal/FFTRealUseTrigo.hpp
vendored
Normal file
91
examples/multimedia/spectrum/3rdparty/fftreal/FFTRealUseTrigo.hpp
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
/*****************************************************************************
|
||||
|
||||
FFTRealUseTrigo.hpp
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if defined (FFTRealUseTrigo_CURRENT_CODEHEADER)
|
||||
#error Recursive inclusion of FFTRealUseTrigo code header.
|
||||
#endif
|
||||
#define FFTRealUseTrigo_CURRENT_CODEHEADER
|
||||
|
||||
#if ! defined (FFTRealUseTrigo_CODEHEADER_INCLUDED)
|
||||
#define FFTRealUseTrigo_CODEHEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include "OscSinCos.h"
|
||||
|
||||
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
template <int ALGO>
|
||||
void FFTRealUseTrigo <ALGO>::prepare (OscType &osc)
|
||||
{
|
||||
osc.clear_buffers ();
|
||||
}
|
||||
|
||||
template <>
|
||||
void FFTRealUseTrigo <0>::prepare (OscType &osc)
|
||||
{
|
||||
// Nothing
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <int ALGO>
|
||||
void FFTRealUseTrigo <ALGO>::iterate (OscType &osc, DataType &c, DataType &s, const DataType cos_ptr [], long index_c, long index_s)
|
||||
{
|
||||
osc.step ();
|
||||
c = osc.get_cos ();
|
||||
s = osc.get_sin ();
|
||||
}
|
||||
|
||||
template <>
|
||||
void FFTRealUseTrigo <0>::iterate (OscType &osc, DataType &c, DataType &s, const DataType cos_ptr [], long index_c, long index_s)
|
||||
{
|
||||
c = cos_ptr [index_c];
|
||||
s = cos_ptr [index_s];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
#endif // FFTRealUseTrigo_CODEHEADER_INCLUDED
|
||||
|
||||
#undef FFTRealUseTrigo_CURRENT_CODEHEADER
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
106
examples/multimedia/spectrum/3rdparty/fftreal/OscSinCos.h
vendored
Normal file
106
examples/multimedia/spectrum/3rdparty/fftreal/OscSinCos.h
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
/*****************************************************************************
|
||||
|
||||
OscSinCos.h
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if ! defined (OscSinCos_HEADER_INCLUDED)
|
||||
#define OscSinCos_HEADER_INCLUDED
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma once
|
||||
#pragma warning (4 : 4250) // "Inherits via dominance."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include "def.h"
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
class OscSinCos
|
||||
{
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
public:
|
||||
|
||||
typedef T DataType;
|
||||
|
||||
OscSinCos ();
|
||||
|
||||
FORCEINLINE void
|
||||
set_step (double angle_rad);
|
||||
|
||||
FORCEINLINE DataType
|
||||
get_cos () const;
|
||||
FORCEINLINE DataType
|
||||
get_sin () const;
|
||||
FORCEINLINE void
|
||||
step ();
|
||||
FORCEINLINE void
|
||||
clear_buffers ();
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
DataType _pos_cos; // Current phase expressed with sin and cos. [-1 ; 1]
|
||||
DataType _pos_sin; // -
|
||||
DataType _step_cos; // Phase increment per step, [-1 ; 1]
|
||||
DataType _step_sin; // -
|
||||
|
||||
|
||||
|
||||
/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
OscSinCos (const OscSinCos &other);
|
||||
OscSinCos & operator = (const OscSinCos &other);
|
||||
bool operator == (const OscSinCos &other);
|
||||
bool operator != (const OscSinCos &other);
|
||||
|
||||
}; // class OscSinCos
|
||||
|
||||
|
||||
|
||||
#include "OscSinCos.hpp"
|
||||
|
||||
|
||||
|
||||
#endif // OscSinCos_HEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
122
examples/multimedia/spectrum/3rdparty/fftreal/OscSinCos.hpp
vendored
Normal file
122
examples/multimedia/spectrum/3rdparty/fftreal/OscSinCos.hpp
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
/*****************************************************************************
|
||||
|
||||
OscSinCos.hpp
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if defined (OscSinCos_CURRENT_CODEHEADER)
|
||||
#error Recursive inclusion of OscSinCos code header.
|
||||
#endif
|
||||
#define OscSinCos_CURRENT_CODEHEADER
|
||||
|
||||
#if ! defined (OscSinCos_CODEHEADER_INCLUDED)
|
||||
#define OscSinCos_CODEHEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace std { }
|
||||
|
||||
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
OscSinCos <T>::OscSinCos ()
|
||||
: _pos_cos (1)
|
||||
, _pos_sin (0)
|
||||
, _step_cos (1)
|
||||
, _step_sin (0)
|
||||
{
|
||||
// Nothing
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
void OscSinCos <T>::set_step (double angle_rad)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
_step_cos = static_cast <DataType> (cos (angle_rad));
|
||||
_step_sin = static_cast <DataType> (sin (angle_rad));
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
typename OscSinCos <T>::DataType OscSinCos <T>::get_cos () const
|
||||
{
|
||||
return (_pos_cos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
typename OscSinCos <T>::DataType OscSinCos <T>::get_sin () const
|
||||
{
|
||||
return (_pos_sin);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
void OscSinCos <T>::step ()
|
||||
{
|
||||
const DataType old_cos = _pos_cos;
|
||||
const DataType old_sin = _pos_sin;
|
||||
|
||||
_pos_cos = old_cos * _step_cos - old_sin * _step_sin;
|
||||
_pos_sin = old_cos * _step_sin + old_sin * _step_cos;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
void OscSinCos <T>::clear_buffers ()
|
||||
{
|
||||
_pos_cos = static_cast <DataType> (1);
|
||||
_pos_sin = static_cast <DataType> (0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
#endif // OscSinCos_CODEHEADER_INCLUDED
|
||||
|
||||
#undef OscSinCos_CURRENT_CODEHEADER
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
105
examples/multimedia/spectrum/3rdparty/fftreal/TestAccuracy.h
vendored
Normal file
105
examples/multimedia/spectrum/3rdparty/fftreal/TestAccuracy.h
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
/*****************************************************************************
|
||||
|
||||
TestAccuracy.h
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if ! defined (TestAccuracy_HEADER_INCLUDED)
|
||||
#define TestAccuracy_HEADER_INCLUDED
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma once
|
||||
#pragma warning (4 : 4250) // "Inherits via dominance."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
template <class FO>
|
||||
class TestAccuracy
|
||||
{
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
public:
|
||||
|
||||
typedef typename FO::DataType DataType;
|
||||
typedef long double BigFloat; // To get maximum accuracy during intermediate calculations
|
||||
|
||||
static int perform_test_single_object (FO &fft);
|
||||
static int perform_test_d (FO &fft, const char *class_name_0);
|
||||
static int perform_test_i (FO &fft, const char *class_name_0);
|
||||
static int perform_test_di (FO &fft, const char *class_name_0);
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
enum { NBR_ACC_TESTS = 10 * 1000 * 1000 };
|
||||
enum { MAX_NBR_TESTS = 10000 };
|
||||
|
||||
static void compute_tf (DataType s [], const DataType x [], long length);
|
||||
static void compute_itf (DataType x [], const DataType s [], long length);
|
||||
static int compare_vect_display (const DataType x_ptr [], const DataType y_ptr [], long len, BigFloat &max_err_rel);
|
||||
static BigFloat
|
||||
compute_power (const DataType x_ptr [], long len);
|
||||
static BigFloat
|
||||
compute_power (const DataType x_ptr [], const DataType y_ptr [], long len);
|
||||
static void compare_vect (const DataType x_ptr [], const DataType y_ptr [], BigFloat &power, long &max_err_pos, long len);
|
||||
|
||||
|
||||
|
||||
/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
TestAccuracy ();
|
||||
~TestAccuracy ();
|
||||
TestAccuracy (const TestAccuracy &other);
|
||||
TestAccuracy & operator = (const TestAccuracy &other);
|
||||
bool operator == (const TestAccuracy &other);
|
||||
bool operator != (const TestAccuracy &other);
|
||||
|
||||
}; // class TestAccuracy
|
||||
|
||||
|
||||
|
||||
#include "TestAccuracy.hpp"
|
||||
|
||||
|
||||
|
||||
#endif // TestAccuracy_HEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
472
examples/multimedia/spectrum/3rdparty/fftreal/TestAccuracy.hpp
vendored
Normal file
472
examples/multimedia/spectrum/3rdparty/fftreal/TestAccuracy.hpp
vendored
Normal file
@@ -0,0 +1,472 @@
|
||||
/*****************************************************************************
|
||||
|
||||
TestAccuracy.hpp
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if defined (TestAccuracy_CURRENT_CODEHEADER)
|
||||
#error Recursive inclusion of TestAccuracy code header.
|
||||
#endif
|
||||
#define TestAccuracy_CURRENT_CODEHEADER
|
||||
|
||||
#if ! defined (TestAccuracy_CODEHEADER_INCLUDED)
|
||||
#define TestAccuracy_CODEHEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include "def.h"
|
||||
#include "test_fnc.h"
|
||||
#include "TestWhiteNoiseGen.h"
|
||||
|
||||
#include <typeinfo>
|
||||
#include <vector>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
|
||||
static const double TestAccuracy_LN10 = 2.3025850929940456840179914546844;
|
||||
|
||||
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
template <class FO>
|
||||
int TestAccuracy <FO>::perform_test_single_object (FO &fft)
|
||||
{
|
||||
assert (&fft != 0);
|
||||
|
||||
using namespace std;
|
||||
|
||||
int ret_val = 0;
|
||||
|
||||
const std::type_info & ti = typeid (fft);
|
||||
const char * class_name_0 = ti.name ();
|
||||
|
||||
if (ret_val == 0)
|
||||
{
|
||||
ret_val = perform_test_d (fft, class_name_0);
|
||||
}
|
||||
if (ret_val == 0)
|
||||
{
|
||||
ret_val = perform_test_i (fft, class_name_0);
|
||||
}
|
||||
if (ret_val == 0)
|
||||
{
|
||||
ret_val = perform_test_di (fft, class_name_0);
|
||||
}
|
||||
|
||||
if (ret_val == 0)
|
||||
{
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
return (ret_val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class FO>
|
||||
int TestAccuracy <FO>::perform_test_d (FO &fft, const char *class_name_0)
|
||||
{
|
||||
assert (&fft != 0);
|
||||
assert (class_name_0 != 0);
|
||||
|
||||
using namespace std;
|
||||
|
||||
int ret_val = 0;
|
||||
const long len = fft.get_length ();
|
||||
const long nbr_tests = limit (
|
||||
NBR_ACC_TESTS / len / len,
|
||||
1L,
|
||||
static_cast <long> (MAX_NBR_TESTS)
|
||||
);
|
||||
|
||||
printf ("Testing %s::do_fft () [%ld samples]... ", class_name_0, len);
|
||||
fflush (stdout);
|
||||
TestWhiteNoiseGen <DataType> noise;
|
||||
std::vector <DataType> x (len);
|
||||
std::vector <DataType> s1 (len);
|
||||
std::vector <DataType> s2 (len);
|
||||
BigFloat err_avg = 0;
|
||||
|
||||
for (long test = 0; test < nbr_tests && ret_val == 0; ++ test)
|
||||
{
|
||||
noise.generate (&x [0], len);
|
||||
fft.do_fft (&s1 [0], &x [0]);
|
||||
compute_tf (&s2 [0], &x [0], len);
|
||||
|
||||
BigFloat max_err;
|
||||
compare_vect_display (&s1 [0], &s2 [0], len, max_err);
|
||||
err_avg += max_err;
|
||||
}
|
||||
err_avg /= NBR_ACC_TESTS;
|
||||
|
||||
printf ("done.\n");
|
||||
printf (
|
||||
"Average maximum error: %.6f %% (%f dB)\n",
|
||||
static_cast <double> (err_avg * 100),
|
||||
static_cast <double> ((20 / TestAccuracy_LN10) * log (err_avg))
|
||||
);
|
||||
|
||||
return (ret_val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class FO>
|
||||
int TestAccuracy <FO>::perform_test_i (FO &fft, const char *class_name_0)
|
||||
{
|
||||
assert (&fft != 0);
|
||||
assert (class_name_0 != 0);
|
||||
|
||||
using namespace std;
|
||||
|
||||
int ret_val = 0;
|
||||
const long len = fft.get_length ();
|
||||
const long nbr_tests = limit (
|
||||
NBR_ACC_TESTS / len / len,
|
||||
10L,
|
||||
static_cast <long> (MAX_NBR_TESTS)
|
||||
);
|
||||
|
||||
printf ("Testing %s::do_ifft () [%ld samples]... ", class_name_0, len);
|
||||
fflush (stdout);
|
||||
TestWhiteNoiseGen <DataType> noise;
|
||||
std::vector <DataType> s (len);
|
||||
std::vector <DataType> x1 (len);
|
||||
std::vector <DataType> x2 (len);
|
||||
BigFloat err_avg = 0;
|
||||
|
||||
for (long test = 0; test < nbr_tests && ret_val == 0; ++ test)
|
||||
{
|
||||
noise.generate (&s [0], len);
|
||||
fft.do_ifft (&s [0], &x1 [0]);
|
||||
compute_itf (&x2 [0], &s [0], len);
|
||||
|
||||
BigFloat max_err;
|
||||
compare_vect_display (&x1 [0], &x2 [0], len, max_err);
|
||||
err_avg += max_err;
|
||||
}
|
||||
err_avg /= NBR_ACC_TESTS;
|
||||
|
||||
printf ("done.\n");
|
||||
printf (
|
||||
"Average maximum error: %.6f %% (%f dB)\n",
|
||||
static_cast <double> (err_avg * 100),
|
||||
static_cast <double> ((20 / TestAccuracy_LN10) * log (err_avg))
|
||||
);
|
||||
|
||||
return (ret_val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class FO>
|
||||
int TestAccuracy <FO>::perform_test_di (FO &fft, const char *class_name_0)
|
||||
{
|
||||
assert (&fft != 0);
|
||||
assert (class_name_0 != 0);
|
||||
|
||||
using namespace std;
|
||||
|
||||
int ret_val = 0;
|
||||
const long len = fft.get_length ();
|
||||
const long nbr_tests = limit (
|
||||
NBR_ACC_TESTS / len / len,
|
||||
1L,
|
||||
static_cast <long> (MAX_NBR_TESTS)
|
||||
);
|
||||
|
||||
printf (
|
||||
"Testing %s::do_fft () / do_ifft () / rescale () [%ld samples]... ",
|
||||
class_name_0,
|
||||
len
|
||||
);
|
||||
fflush (stdout);
|
||||
TestWhiteNoiseGen <DataType> noise;
|
||||
std::vector <DataType> x (len);
|
||||
std::vector <DataType> s (len);
|
||||
std::vector <DataType> y (len);
|
||||
BigFloat err_avg = 0;
|
||||
|
||||
for (long test = 0; test < nbr_tests && ret_val == 0; ++ test)
|
||||
{
|
||||
noise.generate (&x [0], len);
|
||||
fft.do_fft (&s [0], &x [0]);
|
||||
fft.do_ifft (&s [0], &y [0]);
|
||||
fft.rescale (&y [0]);
|
||||
|
||||
BigFloat max_err;
|
||||
compare_vect_display (&x [0], &y [0], len, max_err);
|
||||
err_avg += max_err;
|
||||
}
|
||||
err_avg /= NBR_ACC_TESTS;
|
||||
|
||||
printf ("done.\n");
|
||||
printf (
|
||||
"Average maximum error: %.6f %% (%f dB)\n",
|
||||
static_cast <double> (err_avg * 100),
|
||||
static_cast <double> ((20 / TestAccuracy_LN10) * log (err_avg))
|
||||
);
|
||||
|
||||
return (ret_val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
// Positive transform
|
||||
template <class FO>
|
||||
void TestAccuracy <FO>::compute_tf (DataType s [], const DataType x [], long length)
|
||||
{
|
||||
assert (s != 0);
|
||||
assert (x != 0);
|
||||
assert (length >= 2);
|
||||
assert ((length & 1) == 0);
|
||||
|
||||
const long nbr_bins = length >> 1;
|
||||
|
||||
// DC and Nyquist
|
||||
BigFloat dc = 0;
|
||||
BigFloat ny = 0;
|
||||
for (long pos = 0; pos < length; pos += 2)
|
||||
{
|
||||
const BigFloat even = x [pos ];
|
||||
const BigFloat odd = x [pos + 1];
|
||||
dc += even + odd;
|
||||
ny += even - odd;
|
||||
}
|
||||
s [0 ] = static_cast <DataType> (dc);
|
||||
s [nbr_bins] = static_cast <DataType> (ny);
|
||||
|
||||
// Regular bins
|
||||
for (long bin = 1; bin < nbr_bins; ++ bin)
|
||||
{
|
||||
BigFloat sum_r = 0;
|
||||
BigFloat sum_i = 0;
|
||||
|
||||
const BigFloat m = bin * static_cast <BigFloat> (2 * PI) / length;
|
||||
|
||||
for (long pos = 0; pos < length; ++pos)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
const BigFloat phase = pos * m;
|
||||
const BigFloat e_r = cos (phase);
|
||||
const BigFloat e_i = sin (phase);
|
||||
|
||||
sum_r += x [pos] * e_r;
|
||||
sum_i += x [pos] * e_i;
|
||||
}
|
||||
|
||||
s [ bin] = static_cast <DataType> (sum_r);
|
||||
s [nbr_bins + bin] = static_cast <DataType> (sum_i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Negative transform
|
||||
template <class FO>
|
||||
void TestAccuracy <FO>::compute_itf (DataType x [], const DataType s [], long length)
|
||||
{
|
||||
assert (s != 0);
|
||||
assert (x != 0);
|
||||
assert (length >= 2);
|
||||
assert ((length & 1) == 0);
|
||||
|
||||
const long nbr_bins = length >> 1;
|
||||
|
||||
// DC and Nyquist
|
||||
BigFloat dc = s [0 ];
|
||||
BigFloat ny = s [nbr_bins];
|
||||
|
||||
// Regular bins
|
||||
for (long pos = 0; pos < length; ++pos)
|
||||
{
|
||||
BigFloat sum = dc + ny * (1 - 2 * (pos & 1));
|
||||
|
||||
const BigFloat m = pos * static_cast <BigFloat> (-2 * PI) / length;
|
||||
|
||||
for (long bin = 1; bin < nbr_bins; ++ bin)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
const BigFloat phase = bin * m;
|
||||
const BigFloat e_r = cos (phase);
|
||||
const BigFloat e_i = sin (phase);
|
||||
|
||||
sum += 2 * ( e_r * s [bin ]
|
||||
- e_i * s [bin + nbr_bins]);
|
||||
}
|
||||
|
||||
x [pos] = static_cast <DataType> (sum);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class FO>
|
||||
int TestAccuracy <FO>::compare_vect_display (const DataType x_ptr [], const DataType y_ptr [], long len, BigFloat &max_err_rel)
|
||||
{
|
||||
assert (x_ptr != 0);
|
||||
assert (y_ptr != 0);
|
||||
assert (len > 0);
|
||||
assert (&max_err_rel != 0);
|
||||
|
||||
using namespace std;
|
||||
|
||||
int ret_val = 0;
|
||||
|
||||
BigFloat power = compute_power (&x_ptr [0], &y_ptr [0], len);
|
||||
BigFloat power_dif;
|
||||
long max_err_pos;
|
||||
compare_vect (&x_ptr [0], &y_ptr [0], power_dif, max_err_pos, len);
|
||||
|
||||
if (power == 0)
|
||||
{
|
||||
power = power_dif;
|
||||
}
|
||||
const BigFloat power_err_rel = power_dif / power;
|
||||
|
||||
BigFloat max_err = 0;
|
||||
max_err_rel = 0;
|
||||
if (max_err_pos >= 0)
|
||||
{
|
||||
max_err = y_ptr [max_err_pos] - x_ptr [max_err_pos];
|
||||
max_err_rel = 2 * fabs (max_err) / ( fabs (y_ptr [max_err_pos])
|
||||
+ fabs (x_ptr [max_err_pos]));
|
||||
}
|
||||
|
||||
if (power_err_rel > 0.001)
|
||||
{
|
||||
printf ("Power error : %f (%.6f %%)\n",
|
||||
static_cast <double> (power_err_rel),
|
||||
static_cast <double> (power_err_rel * 100)
|
||||
);
|
||||
if (max_err_pos >= 0)
|
||||
{
|
||||
printf (
|
||||
"Maximum error: %f - %f = %f (%f)\n",
|
||||
static_cast <double> (y_ptr [max_err_pos]),
|
||||
static_cast <double> (x_ptr [max_err_pos]),
|
||||
static_cast <double> (max_err),
|
||||
static_cast <double> (max_err_pos)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (ret_val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class FO>
|
||||
typename TestAccuracy <FO>::BigFloat TestAccuracy <FO>::compute_power (const DataType x_ptr [], long len)
|
||||
{
|
||||
assert (x_ptr != 0);
|
||||
assert (len > 0);
|
||||
|
||||
BigFloat power = 0;
|
||||
for (long pos = 0; pos < len; ++pos)
|
||||
{
|
||||
const BigFloat val = x_ptr [pos];
|
||||
|
||||
power += val * val;
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
|
||||
power = sqrt (power) / len;
|
||||
|
||||
return (power);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class FO>
|
||||
typename TestAccuracy <FO>::BigFloat TestAccuracy <FO>::compute_power (const DataType x_ptr [], const DataType y_ptr [], long len)
|
||||
{
|
||||
assert (x_ptr != 0);
|
||||
assert (y_ptr != 0);
|
||||
assert (len > 0);
|
||||
|
||||
return ((compute_power (x_ptr, len) + compute_power (y_ptr, len)) * 0.5);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class FO>
|
||||
void TestAccuracy <FO>::compare_vect (const DataType x_ptr [], const DataType y_ptr [], BigFloat &power, long &max_err_pos, long len)
|
||||
{
|
||||
assert (x_ptr != 0);
|
||||
assert (y_ptr != 0);
|
||||
assert (len > 0);
|
||||
assert (&power != 0);
|
||||
assert (&max_err_pos != 0);
|
||||
|
||||
power = 0;
|
||||
BigFloat max_dif2 = 0;
|
||||
max_err_pos = -1;
|
||||
|
||||
for (long pos = 0; pos < len; ++pos)
|
||||
{
|
||||
const BigFloat x = x_ptr [pos];
|
||||
const BigFloat y = y_ptr [pos];
|
||||
const BigFloat dif = y - x;
|
||||
const BigFloat dif2 = dif * dif;
|
||||
|
||||
power += dif2;
|
||||
if (dif2 > max_dif2)
|
||||
{
|
||||
max_err_pos = pos;
|
||||
max_dif2 = dif2;
|
||||
}
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
|
||||
power = sqrt (power) / len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // TestAccuracy_CODEHEADER_INCLUDED
|
||||
|
||||
#undef TestAccuracy_CURRENT_CODEHEADER
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
93
examples/multimedia/spectrum/3rdparty/fftreal/TestHelperFixLen.h
vendored
Normal file
93
examples/multimedia/spectrum/3rdparty/fftreal/TestHelperFixLen.h
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
/*****************************************************************************
|
||||
|
||||
TestHelperFixLen.h
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if ! defined (TestHelperFixLen_HEADER_INCLUDED)
|
||||
#define TestHelperFixLen_HEADER_INCLUDED
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma once
|
||||
#pragma warning (4 : 4250) // "Inherits via dominance."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include "FFTRealFixLen.h"
|
||||
|
||||
|
||||
|
||||
template <int L>
|
||||
class TestHelperFixLen
|
||||
{
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
public:
|
||||
|
||||
typedef FFTRealFixLen <L> FftType;
|
||||
|
||||
static void perform_test_accuracy (int &ret_val);
|
||||
static void perform_test_speed (int &ret_val);
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
TestHelperFixLen ();
|
||||
~TestHelperFixLen ();
|
||||
TestHelperFixLen (const TestHelperFixLen &other);
|
||||
TestHelperFixLen &
|
||||
operator = (const TestHelperFixLen &other);
|
||||
bool operator == (const TestHelperFixLen &other);
|
||||
bool operator != (const TestHelperFixLen &other);
|
||||
|
||||
}; // class TestHelperFixLen
|
||||
|
||||
|
||||
|
||||
#include "TestHelperFixLen.hpp"
|
||||
|
||||
|
||||
|
||||
#endif // TestHelperFixLen_HEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
93
examples/multimedia/spectrum/3rdparty/fftreal/TestHelperFixLen.hpp
vendored
Normal file
93
examples/multimedia/spectrum/3rdparty/fftreal/TestHelperFixLen.hpp
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
/*****************************************************************************
|
||||
|
||||
TestHelperFixLen.hpp
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if defined (TestHelperFixLen_CURRENT_CODEHEADER)
|
||||
#error Recursive inclusion of TestHelperFixLen code header.
|
||||
#endif
|
||||
#define TestHelperFixLen_CURRENT_CODEHEADER
|
||||
|
||||
#if ! defined (TestHelperFixLen_CODEHEADER_INCLUDED)
|
||||
#define TestHelperFixLen_CODEHEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include "test_settings.h"
|
||||
|
||||
#include "TestAccuracy.h"
|
||||
#if defined (test_settings_SPEED_TEST_ENABLED)
|
||||
#include "TestSpeed.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
template <int L>
|
||||
void TestHelperFixLen <L>::perform_test_accuracy (int &ret_val)
|
||||
{
|
||||
if (ret_val == 0)
|
||||
{
|
||||
FftType fft;
|
||||
ret_val = TestAccuracy <FftType>::perform_test_single_object (fft);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <int L>
|
||||
void TestHelperFixLen <L>::perform_test_speed (int &ret_val)
|
||||
{
|
||||
#if defined (test_settings_SPEED_TEST_ENABLED)
|
||||
|
||||
if (ret_val == 0)
|
||||
{
|
||||
FftType fft;
|
||||
ret_val = TestSpeed <FftType>::perform_test_single_object (fft);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
#endif // TestHelperFixLen_CODEHEADER_INCLUDED
|
||||
|
||||
#undef TestHelperFixLen_CURRENT_CODEHEADER
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
94
examples/multimedia/spectrum/3rdparty/fftreal/TestHelperNormal.h
vendored
Normal file
94
examples/multimedia/spectrum/3rdparty/fftreal/TestHelperNormal.h
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
/*****************************************************************************
|
||||
|
||||
TestHelperNormal.h
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if ! defined (TestHelperNormal_HEADER_INCLUDED)
|
||||
#define TestHelperNormal_HEADER_INCLUDED
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma once
|
||||
#pragma warning (4 : 4250) // "Inherits via dominance."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include "FFTReal.h"
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
class TestHelperNormal
|
||||
{
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
public:
|
||||
|
||||
typedef DT DataType;
|
||||
typedef FFTReal <DataType> FftType;
|
||||
|
||||
static void perform_test_accuracy (int &ret_val);
|
||||
static void perform_test_speed (int &ret_val);
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
TestHelperNormal ();
|
||||
~TestHelperNormal ();
|
||||
TestHelperNormal (const TestHelperNormal &other);
|
||||
TestHelperNormal &
|
||||
operator = (const TestHelperNormal &other);
|
||||
bool operator == (const TestHelperNormal &other);
|
||||
bool operator != (const TestHelperNormal &other);
|
||||
|
||||
}; // class TestHelperNormal
|
||||
|
||||
|
||||
|
||||
#include "TestHelperNormal.hpp"
|
||||
|
||||
|
||||
|
||||
#endif // TestHelperNormal_HEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
99
examples/multimedia/spectrum/3rdparty/fftreal/TestHelperNormal.hpp
vendored
Normal file
99
examples/multimedia/spectrum/3rdparty/fftreal/TestHelperNormal.hpp
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
/*****************************************************************************
|
||||
|
||||
TestHelperNormal.hpp
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if defined (TestHelperNormal_CURRENT_CODEHEADER)
|
||||
#error Recursive inclusion of TestHelperNormal code header.
|
||||
#endif
|
||||
#define TestHelperNormal_CURRENT_CODEHEADER
|
||||
|
||||
#if ! defined (TestHelperNormal_CODEHEADER_INCLUDED)
|
||||
#define TestHelperNormal_CODEHEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include "test_settings.h"
|
||||
|
||||
#include "TestAccuracy.h"
|
||||
#if defined (test_settings_SPEED_TEST_ENABLED)
|
||||
#include "TestSpeed.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
void TestHelperNormal <DT>::perform_test_accuracy (int &ret_val)
|
||||
{
|
||||
const int len_arr [] = { 1, 2, 3, 4, 7, 8, 10, 12 };
|
||||
const int nbr_len = sizeof (len_arr) / sizeof (len_arr [0]);
|
||||
for (int k = 0; k < nbr_len && ret_val == 0; ++k)
|
||||
{
|
||||
const long len = 1L << (len_arr [k]);
|
||||
FftType fft (len);
|
||||
ret_val = TestAccuracy <FftType>::perform_test_single_object (fft);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
void TestHelperNormal <DT>::perform_test_speed (int &ret_val)
|
||||
{
|
||||
#if defined (test_settings_SPEED_TEST_ENABLED)
|
||||
|
||||
const int len_arr [] = { 1, 2, 3, 4, 7, 8, 10, 12, 14, 16, 18, 20, 22 };
|
||||
const int nbr_len = sizeof (len_arr) / sizeof (len_arr [0]);
|
||||
for (int k = 0; k < nbr_len && ret_val == 0; ++k)
|
||||
{
|
||||
const long len = 1L << (len_arr [k]);
|
||||
FftType fft (len);
|
||||
ret_val = TestSpeed <FftType>::perform_test_single_object (fft);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
#endif // TestHelperNormal_CODEHEADER_INCLUDED
|
||||
|
||||
#undef TestHelperNormal_CURRENT_CODEHEADER
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
95
examples/multimedia/spectrum/3rdparty/fftreal/TestSpeed.h
vendored
Normal file
95
examples/multimedia/spectrum/3rdparty/fftreal/TestSpeed.h
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
/*****************************************************************************
|
||||
|
||||
TestSpeed.h
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if ! defined (TestSpeed_HEADER_INCLUDED)
|
||||
#define TestSpeed_HEADER_INCLUDED
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma once
|
||||
#pragma warning (4 : 4250) // "Inherits via dominance."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
template <class FO>
|
||||
class TestSpeed
|
||||
{
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
public:
|
||||
|
||||
typedef typename FO::DataType DataType;
|
||||
|
||||
static int perform_test_single_object (FO &fft);
|
||||
static int perform_test_d (FO &fft, const char *class_name_0);
|
||||
static int perform_test_i (FO &fft, const char *class_name_0);
|
||||
static int perform_test_di (FO &fft, const char *class_name_0);
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
enum { NBR_SPD_TESTS = 10 * 1000 * 1000 };
|
||||
enum { MAX_NBR_TESTS = 10000 };
|
||||
|
||||
|
||||
|
||||
/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
TestSpeed ();
|
||||
~TestSpeed ();
|
||||
TestSpeed (const TestSpeed &other);
|
||||
TestSpeed & operator = (const TestSpeed &other);
|
||||
bool operator == (const TestSpeed &other);
|
||||
bool operator != (const TestSpeed &other);
|
||||
|
||||
}; // class TestSpeed
|
||||
|
||||
|
||||
|
||||
#include "TestSpeed.hpp"
|
||||
|
||||
|
||||
|
||||
#endif // TestSpeed_HEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
223
examples/multimedia/spectrum/3rdparty/fftreal/TestSpeed.hpp
vendored
Normal file
223
examples/multimedia/spectrum/3rdparty/fftreal/TestSpeed.hpp
vendored
Normal file
@@ -0,0 +1,223 @@
|
||||
/*****************************************************************************
|
||||
|
||||
TestSpeed.hpp
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if defined (TestSpeed_CURRENT_CODEHEADER)
|
||||
#error Recursive inclusion of TestSpeed code header.
|
||||
#endif
|
||||
#define TestSpeed_CURRENT_CODEHEADER
|
||||
|
||||
#if ! defined (TestSpeed_CODEHEADER_INCLUDED)
|
||||
#define TestSpeed_CODEHEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include "test_fnc.h"
|
||||
#include "stopwatch/StopWatch.h"
|
||||
#include "TestWhiteNoiseGen.h"
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
template <class FO>
|
||||
int TestSpeed <FO>::perform_test_single_object (FO &fft)
|
||||
{
|
||||
assert (&fft != 0);
|
||||
|
||||
int ret_val = 0;
|
||||
|
||||
const std::type_info & ti = typeid (fft);
|
||||
const char * class_name_0 = ti.name ();
|
||||
|
||||
if (ret_val == 0)
|
||||
{
|
||||
perform_test_d (fft, class_name_0);
|
||||
}
|
||||
if (ret_val == 0)
|
||||
{
|
||||
perform_test_i (fft, class_name_0);
|
||||
}
|
||||
if (ret_val == 0)
|
||||
{
|
||||
perform_test_di (fft, class_name_0);
|
||||
}
|
||||
|
||||
if (ret_val == 0)
|
||||
{
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
return (ret_val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class FO>
|
||||
int TestSpeed <FO>::perform_test_d (FO &fft, const char *class_name_0)
|
||||
{
|
||||
assert (&fft != 0);
|
||||
assert (class_name_0 != 0);
|
||||
|
||||
const long len = fft.get_length ();
|
||||
const long nbr_tests = limit (
|
||||
static_cast <long> (NBR_SPD_TESTS / len / len),
|
||||
1L,
|
||||
static_cast <long> (MAX_NBR_TESTS)
|
||||
);
|
||||
|
||||
TestWhiteNoiseGen <DataType> noise;
|
||||
std::vector <DataType> x (len, 0);
|
||||
std::vector <DataType> s (len);
|
||||
noise.generate (&x [0], len);
|
||||
|
||||
printf (
|
||||
"%s::do_fft () speed test [%ld samples]... ",
|
||||
class_name_0,
|
||||
len
|
||||
);
|
||||
fflush (stdout);
|
||||
|
||||
stopwatch::StopWatch chrono;
|
||||
chrono.start ();
|
||||
for (long test = 0; test < nbr_tests; ++ test)
|
||||
{
|
||||
fft.do_fft (&s [0], &x [0]);
|
||||
chrono.stop_lap ();
|
||||
}
|
||||
|
||||
printf ("%.1f clocks/sample\n", chrono.get_time_best_lap (len));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class FO>
|
||||
int TestSpeed <FO>::perform_test_i (FO &fft, const char *class_name_0)
|
||||
{
|
||||
assert (&fft != 0);
|
||||
assert (class_name_0 != 0);
|
||||
|
||||
const long len = fft.get_length ();
|
||||
const long nbr_tests = limit (
|
||||
static_cast <long> (NBR_SPD_TESTS / len / len),
|
||||
1L,
|
||||
static_cast <long> (MAX_NBR_TESTS)
|
||||
);
|
||||
|
||||
TestWhiteNoiseGen <DataType> noise;
|
||||
std::vector <DataType> x (len);
|
||||
std::vector <DataType> s (len, 0);
|
||||
noise.generate (&s [0], len);
|
||||
|
||||
printf (
|
||||
"%s::do_ifft () speed test [%ld samples]... ",
|
||||
class_name_0,
|
||||
len
|
||||
);
|
||||
fflush (stdout);
|
||||
|
||||
stopwatch::StopWatch chrono;
|
||||
chrono.start ();
|
||||
for (long test = 0; test < nbr_tests; ++ test)
|
||||
{
|
||||
fft.do_ifft (&s [0], &x [0]);
|
||||
chrono.stop_lap ();
|
||||
}
|
||||
|
||||
printf ("%.1f clocks/sample\n", chrono.get_time_best_lap (len));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class FO>
|
||||
int TestSpeed <FO>::perform_test_di (FO &fft, const char *class_name_0)
|
||||
{
|
||||
assert (&fft != 0);
|
||||
assert (class_name_0 != 0);
|
||||
|
||||
const long len = fft.get_length ();
|
||||
const long nbr_tests = limit (
|
||||
static_cast <long> (NBR_SPD_TESTS / len / len),
|
||||
1L,
|
||||
static_cast <long> (MAX_NBR_TESTS)
|
||||
);
|
||||
|
||||
TestWhiteNoiseGen <DataType> noise;
|
||||
std::vector <DataType> x (len, 0);
|
||||
std::vector <DataType> s (len);
|
||||
std::vector <DataType> y (len);
|
||||
noise.generate (&x [0], len);
|
||||
|
||||
printf (
|
||||
"%s::do_fft () / do_ifft () / rescale () speed test [%ld samples]... ",
|
||||
class_name_0,
|
||||
len
|
||||
);
|
||||
fflush (stdout);
|
||||
|
||||
stopwatch::StopWatch chrono;
|
||||
|
||||
chrono.start ();
|
||||
for (long test = 0; test < nbr_tests; ++ test)
|
||||
{
|
||||
fft.do_fft (&s [0], &x [0]);
|
||||
fft.do_ifft (&s [0], &y [0]);
|
||||
fft.rescale (&y [0]);
|
||||
chrono.stop_lap ();
|
||||
}
|
||||
|
||||
printf ("%.1f clocks/sample\n", chrono.get_time_best_lap (len));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
#endif // TestSpeed_CODEHEADER_INCLUDED
|
||||
|
||||
#undef TestSpeed_CURRENT_CODEHEADER
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
95
examples/multimedia/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.h
vendored
Normal file
95
examples/multimedia/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.h
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
/*****************************************************************************
|
||||
|
||||
TestWhiteNoiseGen.h
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if ! defined (TestWhiteNoiseGen_HEADER_INCLUDED)
|
||||
#define TestWhiteNoiseGen_HEADER_INCLUDED
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma once
|
||||
#pragma warning (4 : 4250) // "Inherits via dominance."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
class TestWhiteNoiseGen
|
||||
{
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
public:
|
||||
|
||||
typedef DT DataType;
|
||||
|
||||
TestWhiteNoiseGen ();
|
||||
virtual ~TestWhiteNoiseGen () {}
|
||||
|
||||
void generate (DataType data_ptr [], long len);
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
typedef unsigned long StateType;
|
||||
|
||||
StateType _rand_state;
|
||||
|
||||
|
||||
|
||||
/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
TestWhiteNoiseGen (const TestWhiteNoiseGen &other);
|
||||
TestWhiteNoiseGen &
|
||||
operator = (const TestWhiteNoiseGen &other);
|
||||
bool operator == (const TestWhiteNoiseGen &other);
|
||||
bool operator != (const TestWhiteNoiseGen &other);
|
||||
|
||||
}; // class TestWhiteNoiseGen
|
||||
|
||||
|
||||
|
||||
#include "TestWhiteNoiseGen.hpp"
|
||||
|
||||
|
||||
|
||||
#endif // TestWhiteNoiseGen_HEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
91
examples/multimedia/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.hpp
vendored
Normal file
91
examples/multimedia/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.hpp
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
/*****************************************************************************
|
||||
|
||||
TestWhiteNoiseGen.hpp
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if defined (TestWhiteNoiseGen_CURRENT_CODEHEADER)
|
||||
#error Recursive inclusion of TestWhiteNoiseGen code header.
|
||||
#endif
|
||||
#define TestWhiteNoiseGen_CURRENT_CODEHEADER
|
||||
|
||||
#if ! defined (TestWhiteNoiseGen_CODEHEADER_INCLUDED)
|
||||
#define TestWhiteNoiseGen_CODEHEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
TestWhiteNoiseGen <DT>::TestWhiteNoiseGen ()
|
||||
: _rand_state (0)
|
||||
{
|
||||
_rand_state = reinterpret_cast <StateType> (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class DT>
|
||||
void TestWhiteNoiseGen <DT>::generate (DataType data_ptr [], long len)
|
||||
{
|
||||
assert (data_ptr != 0);
|
||||
assert (len > 0);
|
||||
|
||||
const DataType one = static_cast <DataType> (1);
|
||||
const DataType mul = one / static_cast <DataType> (0x80000000UL);
|
||||
|
||||
long pos = 0;
|
||||
do
|
||||
{
|
||||
const DataType x = static_cast <DataType> (_rand_state & 0xFFFFFFFFUL);
|
||||
data_ptr [pos] = x * mul - one;
|
||||
|
||||
_rand_state = _rand_state * 1234567UL + 890123UL;
|
||||
|
||||
++ pos;
|
||||
}
|
||||
while (pos < len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
#endif // TestWhiteNoiseGen_CODEHEADER_INCLUDED
|
||||
|
||||
#undef TestWhiteNoiseGen_CURRENT_CODEHEADER
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
5
examples/multimedia/spectrum/3rdparty/fftreal/bwins/fftrealu.def
vendored
Normal file
5
examples/multimedia/spectrum/3rdparty/fftreal/bwins/fftrealu.def
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
EXPORTS
|
||||
??0FFTRealWrapper@@QAE@XZ @ 1 NONAME ; FFTRealWrapper::FFTRealWrapper(void)
|
||||
??1FFTRealWrapper@@QAE@XZ @ 2 NONAME ; FFTRealWrapper::~FFTRealWrapper(void)
|
||||
?calculateFFT@FFTRealWrapper@@QAEXQAMQBM@Z @ 3 NONAME ; void FFTRealWrapper::calculateFFT(float * const, float const * const)
|
||||
|
||||
60
examples/multimedia/spectrum/3rdparty/fftreal/def.h
vendored
Normal file
60
examples/multimedia/spectrum/3rdparty/fftreal/def.h
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
/*****************************************************************************
|
||||
|
||||
def.h
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if ! defined (def_HEADER_INCLUDED)
|
||||
#define def_HEADER_INCLUDED
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma once
|
||||
#pragma warning (4 : 4250) // "Inherits via dominance."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
|
||||
const double PI = 3.1415926535897932384626433832795;
|
||||
const double SQRT2 = 1.41421356237309514547462185873883;
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
|
||||
#define FORCEINLINE __forceinline
|
||||
|
||||
#else
|
||||
|
||||
#define FORCEINLINE inline
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif // def_HEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
7
examples/multimedia/spectrum/3rdparty/fftreal/eabi/fftrealu.def
vendored
Normal file
7
examples/multimedia/spectrum/3rdparty/fftreal/eabi/fftrealu.def
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
EXPORTS
|
||||
_ZN14FFTRealWrapper12calculateFFTEPfPKf @ 1 NONAME
|
||||
_ZN14FFTRealWrapperC1Ev @ 2 NONAME
|
||||
_ZN14FFTRealWrapperC2Ev @ 3 NONAME
|
||||
_ZN14FFTRealWrapperD1Ev @ 4 NONAME
|
||||
_ZN14FFTRealWrapperD2Ev @ 5 NONAME
|
||||
|
||||
661
examples/multimedia/spectrum/3rdparty/fftreal/fftreal.pas
vendored
Normal file
661
examples/multimedia/spectrum/3rdparty/fftreal/fftreal.pas
vendored
Normal file
@@ -0,0 +1,661 @@
|
||||
(*****************************************************************************
|
||||
|
||||
DIGITAL SIGNAL PROCESSING TOOLS
|
||||
Version 1.03, 2001/06/15
|
||||
(c) 1999 - Laurent de Soras
|
||||
|
||||
FFTReal.h
|
||||
Fourier transformation of real number arrays.
|
||||
Portable ISO C++
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
LEGAL
|
||||
|
||||
Source code may be freely used for any purpose, including commercial
|
||||
applications. Programs must display in their "About" dialog-box (or
|
||||
documentation) a text telling they use these routines by Laurent de Soras.
|
||||
Modified source code can be distributed, but modifications must be clearly
|
||||
indicated.
|
||||
|
||||
CONTACT
|
||||
|
||||
Laurent de Soras
|
||||
92 avenue Albert 1er
|
||||
92500 Rueil-Malmaison
|
||||
France
|
||||
|
||||
ldesoras@club-internet.fr
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Translation to ObjectPascal by :
|
||||
Frederic Vanmol
|
||||
frederic@axiworld.be
|
||||
|
||||
*****************************************************************************)
|
||||
|
||||
|
||||
unit
|
||||
FFTReal;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Windows;
|
||||
|
||||
(* Change this typedef to use a different floating point type in your FFTs
|
||||
(i.e. float, double or long double). *)
|
||||
type
|
||||
pflt_t = ^flt_t;
|
||||
flt_t = single;
|
||||
|
||||
pflt_array = ^flt_array;
|
||||
flt_array = array[0..0] of flt_t;
|
||||
|
||||
plongarray = ^longarray;
|
||||
longarray = array[0..0] of longint;
|
||||
|
||||
const
|
||||
sizeof_flt : longint = SizeOf(flt_t);
|
||||
|
||||
|
||||
|
||||
type
|
||||
// Bit reversed look-up table nested class
|
||||
TBitReversedLUT = class
|
||||
private
|
||||
_ptr : plongint;
|
||||
public
|
||||
constructor Create(const nbr_bits: integer);
|
||||
destructor Destroy; override;
|
||||
function get_ptr: plongint;
|
||||
end;
|
||||
|
||||
// Trigonometric look-up table nested class
|
||||
TTrigoLUT = class
|
||||
private
|
||||
_ptr : pflt_t;
|
||||
public
|
||||
constructor Create(const nbr_bits: integer);
|
||||
destructor Destroy; override;
|
||||
function get_ptr(const level: integer): pflt_t;
|
||||
end;
|
||||
|
||||
TFFTReal = class
|
||||
private
|
||||
_bit_rev_lut : TBitReversedLUT;
|
||||
_trigo_lut : TTrigoLUT;
|
||||
_sqrt2_2 : flt_t;
|
||||
_length : longint;
|
||||
_nbr_bits : integer;
|
||||
_buffer_ptr : pflt_t;
|
||||
public
|
||||
constructor Create(const length: longint);
|
||||
destructor Destroy; override;
|
||||
|
||||
procedure do_fft(f: pflt_array; const x: pflt_array);
|
||||
procedure do_ifft(const f: pflt_array; x: pflt_array);
|
||||
procedure rescale(x: pflt_array);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
Math;
|
||||
|
||||
{ TBitReversedLUT }
|
||||
|
||||
constructor TBitReversedLUT.Create(const nbr_bits: integer);
|
||||
var
|
||||
length : longint;
|
||||
cnt : longint;
|
||||
br_index : longint;
|
||||
bit : longint;
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
length := 1 shl nbr_bits;
|
||||
GetMem(_ptr, length*SizeOf(longint));
|
||||
|
||||
br_index := 0;
|
||||
plongarray(_ptr)^[0] := 0;
|
||||
for cnt := 1 to length-1 do
|
||||
begin
|
||||
// ++br_index (bit reversed)
|
||||
bit := length shr 1;
|
||||
br_index := br_index xor bit;
|
||||
while br_index and bit = 0 do
|
||||
begin
|
||||
bit := bit shr 1;
|
||||
br_index := br_index xor bit;
|
||||
end;
|
||||
|
||||
plongarray(_ptr)^[cnt] := br_index;
|
||||
end;
|
||||
end;
|
||||
|
||||
destructor TBitReversedLUT.Destroy;
|
||||
begin
|
||||
FreeMem(_ptr);
|
||||
_ptr := nil;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
function TBitReversedLUT.get_ptr: plongint;
|
||||
begin
|
||||
Result := _ptr;
|
||||
end;
|
||||
|
||||
{ TTrigLUT }
|
||||
|
||||
constructor TTrigoLUT.Create(const nbr_bits: integer);
|
||||
var
|
||||
total_len : longint;
|
||||
PI : double;
|
||||
level : integer;
|
||||
level_len : longint;
|
||||
level_ptr : pflt_array;
|
||||
mul : double;
|
||||
i : longint;
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
_ptr := nil;
|
||||
|
||||
if (nbr_bits > 3) then
|
||||
begin
|
||||
total_len := (1 shl (nbr_bits - 1)) - 4;
|
||||
GetMem(_ptr, total_len * sizeof_flt);
|
||||
|
||||
PI := ArcTan(1) * 4;
|
||||
for level := 3 to nbr_bits-1 do
|
||||
begin
|
||||
level_len := 1 shl (level - 1);
|
||||
level_ptr := pointer(get_ptr(level));
|
||||
mul := PI / (level_len shl 1);
|
||||
|
||||
for i := 0 to level_len-1 do
|
||||
level_ptr^[i] := cos(i * mul);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
destructor TTrigoLUT.Destroy;
|
||||
begin
|
||||
FreeMem(_ptr);
|
||||
_ptr := nil;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
function TTrigoLUT.get_ptr(const level: integer): pflt_t;
|
||||
var
|
||||
tempp : pflt_t;
|
||||
begin
|
||||
tempp := _ptr;
|
||||
inc(tempp, (1 shl (level-1)) - 4);
|
||||
Result := tempp;
|
||||
end;
|
||||
|
||||
{ TFFTReal }
|
||||
|
||||
constructor TFFTReal.Create(const length: longint);
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
_length := length;
|
||||
_nbr_bits := Floor(Ln(length) / Ln(2) + 0.5);
|
||||
_bit_rev_lut := TBitReversedLUT.Create(Floor(Ln(length) / Ln(2) + 0.5));
|
||||
_trigo_lut := TTrigoLUT.Create(Floor(Ln(length) / Ln(2) + 0.05));
|
||||
_sqrt2_2 := Sqrt(2) * 0.5;
|
||||
|
||||
_buffer_ptr := nil;
|
||||
if _nbr_bits > 2 then
|
||||
GetMem(_buffer_ptr, _length * sizeof_flt);
|
||||
end;
|
||||
|
||||
destructor TFFTReal.Destroy;
|
||||
begin
|
||||
if _buffer_ptr <> nil then
|
||||
begin
|
||||
FreeMem(_buffer_ptr);
|
||||
_buffer_ptr := nil;
|
||||
end;
|
||||
|
||||
_bit_rev_lut.Free;
|
||||
_bit_rev_lut := nil;
|
||||
_trigo_lut.Free;
|
||||
_trigo_lut := nil;
|
||||
|
||||
inherited;
|
||||
end;
|
||||
|
||||
(*==========================================================================*/
|
||||
/* Name: do_fft */
|
||||
/* Description: Compute the FFT of the array. */
|
||||
/* Input parameters: */
|
||||
/* - x: pointer on the source array (time). */
|
||||
/* Output parameters: */
|
||||
/* - f: pointer on the destination array (frequencies). */
|
||||
/* f [0...length(x)/2] = real values, */
|
||||
/* f [length(x)/2+1...length(x)-1] = imaginary values of */
|
||||
/* coefficents 1...length(x)/2-1. */
|
||||
/*==========================================================================*)
|
||||
procedure TFFTReal.do_fft(f: pflt_array; const x: pflt_array);
|
||||
var
|
||||
sf, df : pflt_array;
|
||||
pass : integer;
|
||||
nbr_coef : longint;
|
||||
h_nbr_coef : longint;
|
||||
d_nbr_coef : longint;
|
||||
coef_index : longint;
|
||||
bit_rev_lut_ptr : plongarray;
|
||||
rev_index_0 : longint;
|
||||
rev_index_1 : longint;
|
||||
rev_index_2 : longint;
|
||||
rev_index_3 : longint;
|
||||
df2 : pflt_array;
|
||||
n1, n2, n3 : integer;
|
||||
sf_0, sf_2 : flt_t;
|
||||
sqrt2_2 : flt_t;
|
||||
v : flt_t;
|
||||
cos_ptr : pflt_array;
|
||||
i : longint;
|
||||
sf1r, sf2r : pflt_array;
|
||||
dfr, dfi : pflt_array;
|
||||
sf1i, sf2i : pflt_array;
|
||||
c, s : flt_t;
|
||||
temp_ptr : pflt_array;
|
||||
b_0, b_2 : flt_t;
|
||||
begin
|
||||
n1 := 1;
|
||||
n2 := 2;
|
||||
n3 := 3;
|
||||
|
||||
(*______________________________________________
|
||||
*
|
||||
* General case
|
||||
*______________________________________________
|
||||
*)
|
||||
|
||||
if _nbr_bits > 2 then
|
||||
begin
|
||||
if _nbr_bits and 1 <> 0 then
|
||||
begin
|
||||
df := pointer(_buffer_ptr);
|
||||
sf := f;
|
||||
end
|
||||
else
|
||||
begin
|
||||
df := f;
|
||||
sf := pointer(_buffer_ptr);
|
||||
end;
|
||||
|
||||
//
|
||||
// Do the transformation in several passes
|
||||
//
|
||||
|
||||
// First and second pass at once
|
||||
bit_rev_lut_ptr := pointer(_bit_rev_lut.get_ptr);
|
||||
coef_index := 0;
|
||||
|
||||
repeat
|
||||
rev_index_0 := bit_rev_lut_ptr^[coef_index];
|
||||
rev_index_1 := bit_rev_lut_ptr^[coef_index + 1];
|
||||
rev_index_2 := bit_rev_lut_ptr^[coef_index + 2];
|
||||
rev_index_3 := bit_rev_lut_ptr^[coef_index + 3];
|
||||
|
||||
df2 := pointer(longint(df) + (coef_index*sizeof_flt));
|
||||
df2^[n1] := x^[rev_index_0] - x^[rev_index_1];
|
||||
df2^[n3] := x^[rev_index_2] - x^[rev_index_3];
|
||||
|
||||
sf_0 := x^[rev_index_0] + x^[rev_index_1];
|
||||
sf_2 := x^[rev_index_2] + x^[rev_index_3];
|
||||
|
||||
df2^[0] := sf_0 + sf_2;
|
||||
df2^[n2] := sf_0 - sf_2;
|
||||
|
||||
inc(coef_index, 4);
|
||||
until (coef_index >= _length);
|
||||
|
||||
|
||||
// Third pass
|
||||
coef_index := 0;
|
||||
sqrt2_2 := _sqrt2_2;
|
||||
|
||||
repeat
|
||||
sf^[coef_index] := df^[coef_index] + df^[coef_index + 4];
|
||||
sf^[coef_index + 4] := df^[coef_index] - df^[coef_index + 4];
|
||||
sf^[coef_index + 2] := df^[coef_index + 2];
|
||||
sf^[coef_index + 6] := df^[coef_index + 6];
|
||||
|
||||
v := (df [coef_index + 5] - df^[coef_index + 7]) * sqrt2_2;
|
||||
sf^[coef_index + 1] := df^[coef_index + 1] + v;
|
||||
sf^[coef_index + 3] := df^[coef_index + 1] - v;
|
||||
|
||||
v := (df^[coef_index + 5] + df^[coef_index + 7]) * sqrt2_2;
|
||||
sf [coef_index + 5] := v + df^[coef_index + 3];
|
||||
sf [coef_index + 7] := v - df^[coef_index + 3];
|
||||
|
||||
inc(coef_index, 8);
|
||||
until (coef_index >= _length);
|
||||
|
||||
|
||||
// Next pass
|
||||
for pass := 3 to _nbr_bits-1 do
|
||||
begin
|
||||
coef_index := 0;
|
||||
nbr_coef := 1 shl pass;
|
||||
h_nbr_coef := nbr_coef shr 1;
|
||||
d_nbr_coef := nbr_coef shl 1;
|
||||
|
||||
cos_ptr := pointer(_trigo_lut.get_ptr(pass));
|
||||
repeat
|
||||
sf1r := pointer(longint(sf) + (coef_index * sizeof_flt));
|
||||
sf2r := pointer(longint(sf1r) + (nbr_coef * sizeof_flt));
|
||||
dfr := pointer(longint(df) + (coef_index * sizeof_flt));
|
||||
dfi := pointer(longint(dfr) + (nbr_coef * sizeof_flt));
|
||||
|
||||
// Extreme coefficients are always real
|
||||
dfr^[0] := sf1r^[0] + sf2r^[0];
|
||||
dfi^[0] := sf1r^[0] - sf2r^[0]; // dfr [nbr_coef] =
|
||||
dfr^[h_nbr_coef] := sf1r^[h_nbr_coef];
|
||||
dfi^[h_nbr_coef] := sf2r^[h_nbr_coef];
|
||||
|
||||
// Others are conjugate complex numbers
|
||||
sf1i := pointer(longint(sf1r) + (h_nbr_coef * sizeof_flt));
|
||||
sf2i := pointer(longint(sf1i) + (nbr_coef * sizeof_flt));
|
||||
|
||||
for i := 1 to h_nbr_coef-1 do
|
||||
begin
|
||||
c := cos_ptr^[i]; // cos (i*PI/nbr_coef);
|
||||
s := cos_ptr^[h_nbr_coef - i]; // sin (i*PI/nbr_coef);
|
||||
|
||||
v := sf2r^[i] * c - sf2i^[i] * s;
|
||||
dfr^[i] := sf1r^[i] + v;
|
||||
dfi^[-i] := sf1r^[i] - v; // dfr [nbr_coef - i] =
|
||||
|
||||
v := sf2r^[i] * s + sf2i^[i] * c;
|
||||
dfi^[i] := v + sf1i^[i];
|
||||
dfi^[nbr_coef - i] := v - sf1i^[i];
|
||||
end;
|
||||
|
||||
inc(coef_index, d_nbr_coef);
|
||||
until (coef_index >= _length);
|
||||
|
||||
// Prepare to the next pass
|
||||
temp_ptr := df;
|
||||
df := sf;
|
||||
sf := temp_ptr;
|
||||
end;
|
||||
end
|
||||
|
||||
(*______________________________________________
|
||||
*
|
||||
* Special cases
|
||||
*______________________________________________
|
||||
*)
|
||||
|
||||
// 4-point FFT
|
||||
else if _nbr_bits = 2 then
|
||||
begin
|
||||
f^[n1] := x^[0] - x^[n2];
|
||||
f^[n3] := x^[n1] - x^[n3];
|
||||
|
||||
b_0 := x^[0] + x^[n2];
|
||||
b_2 := x^[n1] + x^[n3];
|
||||
|
||||
f^[0] := b_0 + b_2;
|
||||
f^[n2] := b_0 - b_2;
|
||||
end
|
||||
|
||||
// 2-point FFT
|
||||
else if _nbr_bits = 1 then
|
||||
begin
|
||||
f^[0] := x^[0] + x^[n1];
|
||||
f^[n1] := x^[0] - x^[n1];
|
||||
end
|
||||
|
||||
// 1-point FFT
|
||||
else
|
||||
f^[0] := x^[0];
|
||||
end;
|
||||
|
||||
|
||||
(*==========================================================================*/
|
||||
/* Name: do_ifft */
|
||||
/* Description: Compute the inverse FFT of the array. Notice that */
|
||||
/* IFFT (FFT (x)) = x * length (x). Data must be */
|
||||
/* post-scaled. */
|
||||
/* Input parameters: */
|
||||
/* - f: pointer on the source array (frequencies). */
|
||||
/* f [0...length(x)/2] = real values, */
|
||||
/* f [length(x)/2+1...length(x)-1] = imaginary values of */
|
||||
/* coefficents 1...length(x)/2-1. */
|
||||
/* Output parameters: */
|
||||
/* - x: pointer on the destination array (time). */
|
||||
/*==========================================================================*)
|
||||
procedure TFFTReal.do_ifft(const f: pflt_array; x: pflt_array);
|
||||
var
|
||||
n1, n2, n3 : integer;
|
||||
n4, n5, n6, n7 : integer;
|
||||
sf, df, df_temp : pflt_array;
|
||||
pass : integer;
|
||||
nbr_coef : longint;
|
||||
h_nbr_coef : longint;
|
||||
d_nbr_coef : longint;
|
||||
coef_index : longint;
|
||||
cos_ptr : pflt_array;
|
||||
i : longint;
|
||||
sfr, sfi : pflt_array;
|
||||
df1r, df2r : pflt_array;
|
||||
df1i, df2i : pflt_array;
|
||||
c, s, vr, vi : flt_t;
|
||||
temp_ptr : pflt_array;
|
||||
sqrt2_2 : flt_t;
|
||||
bit_rev_lut_ptr : plongarray;
|
||||
sf2 : pflt_array;
|
||||
b_0, b_1, b_2, b_3 : flt_t;
|
||||
begin
|
||||
n1 := 1;
|
||||
n2 := 2;
|
||||
n3 := 3;
|
||||
n4 := 4;
|
||||
n5 := 5;
|
||||
n6 := 6;
|
||||
n7 := 7;
|
||||
|
||||
(*______________________________________________
|
||||
*
|
||||
* General case
|
||||
*______________________________________________
|
||||
*)
|
||||
|
||||
if _nbr_bits > 2 then
|
||||
begin
|
||||
sf := f;
|
||||
|
||||
if _nbr_bits and 1 <> 0 then
|
||||
begin
|
||||
df := pointer(_buffer_ptr);
|
||||
df_temp := x;
|
||||
end
|
||||
else
|
||||
begin
|
||||
df := x;
|
||||
df_temp := pointer(_buffer_ptr);
|
||||
end;
|
||||
|
||||
// Do the transformation in several pass
|
||||
|
||||
// First pass
|
||||
for pass := _nbr_bits-1 downto 3 do
|
||||
begin
|
||||
coef_index := 0;
|
||||
nbr_coef := 1 shl pass;
|
||||
h_nbr_coef := nbr_coef shr 1;
|
||||
d_nbr_coef := nbr_coef shl 1;
|
||||
|
||||
cos_ptr := pointer(_trigo_lut.get_ptr(pass));
|
||||
|
||||
repeat
|
||||
sfr := pointer(longint(sf) + (coef_index*sizeof_flt));
|
||||
sfi := pointer(longint(sfr) + (nbr_coef*sizeof_flt));
|
||||
df1r := pointer(longint(df) + (coef_index*sizeof_flt));
|
||||
df2r := pointer(longint(df1r) + (nbr_coef*sizeof_flt));
|
||||
|
||||
// Extreme coefficients are always real
|
||||
df1r^[0] := sfr^[0] + sfi^[0]; // + sfr [nbr_coef]
|
||||
df2r^[0] := sfr^[0] - sfi^[0]; // - sfr [nbr_coef]
|
||||
df1r^[h_nbr_coef] := sfr^[h_nbr_coef] * 2;
|
||||
df2r^[h_nbr_coef] := sfi^[h_nbr_coef] * 2;
|
||||
|
||||
// Others are conjugate complex numbers
|
||||
df1i := pointer(longint(df1r) + (h_nbr_coef*sizeof_flt));
|
||||
df2i := pointer(longint(df1i) + (nbr_coef*sizeof_flt));
|
||||
|
||||
for i := 1 to h_nbr_coef-1 do
|
||||
begin
|
||||
df1r^[i] := sfr^[i] + sfi^[-i]; // + sfr [nbr_coef - i]
|
||||
df1i^[i] := sfi^[i] - sfi^[nbr_coef - i];
|
||||
|
||||
c := cos_ptr^[i]; // cos (i*PI/nbr_coef);
|
||||
s := cos_ptr^[h_nbr_coef - i]; // sin (i*PI/nbr_coef);
|
||||
vr := sfr^[i] - sfi^[-i]; // - sfr [nbr_coef - i]
|
||||
vi := sfi^[i] + sfi^[nbr_coef - i];
|
||||
|
||||
df2r^[i] := vr * c + vi * s;
|
||||
df2i^[i] := vi * c - vr * s;
|
||||
end;
|
||||
|
||||
inc(coef_index, d_nbr_coef);
|
||||
until (coef_index >= _length);
|
||||
|
||||
|
||||
// Prepare to the next pass
|
||||
if (pass < _nbr_bits - 1) then
|
||||
begin
|
||||
temp_ptr := df;
|
||||
df := sf;
|
||||
sf := temp_ptr;
|
||||
end
|
||||
else
|
||||
begin
|
||||
sf := df;
|
||||
df := df_temp;
|
||||
end
|
||||
end;
|
||||
|
||||
// Antepenultimate pass
|
||||
sqrt2_2 := _sqrt2_2;
|
||||
coef_index := 0;
|
||||
|
||||
repeat
|
||||
df^[coef_index] := sf^[coef_index] + sf^[coef_index + 4];
|
||||
df^[coef_index + 4] := sf^[coef_index] - sf^[coef_index + 4];
|
||||
df^[coef_index + 2] := sf^[coef_index + 2] * 2;
|
||||
df^[coef_index + 6] := sf^[coef_index + 6] * 2;
|
||||
|
||||
df^[coef_index + 1] := sf^[coef_index + 1] + sf^[coef_index + 3];
|
||||
df^[coef_index + 3] := sf^[coef_index + 5] - sf^[coef_index + 7];
|
||||
|
||||
vr := sf^[coef_index + 1] - sf^[coef_index + 3];
|
||||
vi := sf^[coef_index + 5] + sf^[coef_index + 7];
|
||||
|
||||
df^[coef_index + 5] := (vr + vi) * sqrt2_2;
|
||||
df^[coef_index + 7] := (vi - vr) * sqrt2_2;
|
||||
|
||||
inc(coef_index, 8);
|
||||
until (coef_index >= _length);
|
||||
|
||||
|
||||
// Penultimate and last pass at once
|
||||
coef_index := 0;
|
||||
bit_rev_lut_ptr := pointer(_bit_rev_lut.get_ptr);
|
||||
sf2 := df;
|
||||
|
||||
repeat
|
||||
b_0 := sf2^[0] + sf2^[n2];
|
||||
b_2 := sf2^[0] - sf2^[n2];
|
||||
b_1 := sf2^[n1] * 2;
|
||||
b_3 := sf2^[n3] * 2;
|
||||
|
||||
x^[bit_rev_lut_ptr^[0]] := b_0 + b_1;
|
||||
x^[bit_rev_lut_ptr^[n1]] := b_0 - b_1;
|
||||
x^[bit_rev_lut_ptr^[n2]] := b_2 + b_3;
|
||||
x^[bit_rev_lut_ptr^[n3]] := b_2 - b_3;
|
||||
|
||||
b_0 := sf2^[n4] + sf2^[n6];
|
||||
b_2 := sf2^[n4] - sf2^[n6];
|
||||
b_1 := sf2^[n5] * 2;
|
||||
b_3 := sf2^[n7] * 2;
|
||||
|
||||
x^[bit_rev_lut_ptr^[n4]] := b_0 + b_1;
|
||||
x^[bit_rev_lut_ptr^[n5]] := b_0 - b_1;
|
||||
x^[bit_rev_lut_ptr^[n6]] := b_2 + b_3;
|
||||
x^[bit_rev_lut_ptr^[n7]] := b_2 - b_3;
|
||||
|
||||
inc(sf2, 8);
|
||||
inc(coef_index, 8);
|
||||
inc(bit_rev_lut_ptr, 8);
|
||||
until (coef_index >= _length);
|
||||
end
|
||||
|
||||
(*______________________________________________
|
||||
*
|
||||
* Special cases
|
||||
*______________________________________________
|
||||
*)
|
||||
|
||||
// 4-point IFFT
|
||||
else if _nbr_bits = 2 then
|
||||
begin
|
||||
b_0 := f^[0] + f [n2];
|
||||
b_2 := f^[0] - f [n2];
|
||||
|
||||
x^[0] := b_0 + f [n1] * 2;
|
||||
x^[n2] := b_0 - f [n1] * 2;
|
||||
x^[n1] := b_2 + f [n3] * 2;
|
||||
x^[n3] := b_2 - f [n3] * 2;
|
||||
end
|
||||
|
||||
// 2-point IFFT
|
||||
else if _nbr_bits = 1 then
|
||||
begin
|
||||
x^[0] := f^[0] + f^[n1];
|
||||
x^[n1] := f^[0] - f^[n1];
|
||||
end
|
||||
|
||||
// 1-point IFFT
|
||||
else
|
||||
x^[0] := f^[0];
|
||||
end;
|
||||
|
||||
(*==========================================================================*/
|
||||
/* Name: rescale */
|
||||
/* Description: Scale an array by divide each element by its length. */
|
||||
/* This function should be called after FFT + IFFT. */
|
||||
/* Input/Output parameters: */
|
||||
/* - x: pointer on array to rescale (time or frequency). */
|
||||
/*==========================================================================*)
|
||||
procedure TFFTReal.rescale(x: pflt_array);
|
||||
var
|
||||
mul : flt_t;
|
||||
i : longint;
|
||||
begin
|
||||
mul := 1.0 / _length;
|
||||
i := _length - 1;
|
||||
|
||||
repeat
|
||||
x^[i] := x^[i] * mul;
|
||||
dec(i);
|
||||
until (i < 0);
|
||||
end;
|
||||
|
||||
end.
|
||||
44
examples/multimedia/spectrum/3rdparty/fftreal/fftreal.pro
vendored
Normal file
44
examples/multimedia/spectrum/3rdparty/fftreal/fftreal.pro
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
include(../../spectrum.pri)
|
||||
|
||||
static: error(This library cannot be built for static linkage)
|
||||
|
||||
TEMPLATE = lib
|
||||
TARGET = fftreal
|
||||
|
||||
# FFTReal
|
||||
HEADERS += Array.h \
|
||||
Array.hpp \
|
||||
DynArray.h \
|
||||
DynArray.hpp \
|
||||
FFTRealFixLen.h \
|
||||
FFTRealFixLen.hpp \
|
||||
FFTRealFixLenParam.h \
|
||||
FFTRealPassDirect.h \
|
||||
FFTRealPassDirect.hpp \
|
||||
FFTRealPassInverse.h \
|
||||
FFTRealPassInverse.hpp \
|
||||
FFTRealSelect.h \
|
||||
FFTRealSelect.hpp \
|
||||
FFTRealUseTrigo.h \
|
||||
FFTRealUseTrigo.hpp \
|
||||
OscSinCos.h \
|
||||
OscSinCos.hpp \
|
||||
def.h
|
||||
|
||||
# Wrapper used to export the required instantiation of the FFTRealFixLen template
|
||||
HEADERS += fftreal_wrapper.h
|
||||
SOURCES += fftreal_wrapper.cpp
|
||||
|
||||
DEFINES += FFTREAL_LIBRARY
|
||||
|
||||
macx {
|
||||
CONFIG += lib_bundle
|
||||
} else {
|
||||
DESTDIR = ../..$${spectrum_build_dir}
|
||||
}
|
||||
|
||||
EXAMPLE_FILES = bwins/fftreal.def eabi/fftreal.def readme.txt license.txt
|
||||
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/spectrum
|
||||
INSTALLS += target
|
||||
|
||||
54
examples/multimedia/spectrum/3rdparty/fftreal/fftreal_wrapper.cpp
vendored
Normal file
54
examples/multimedia/spectrum/3rdparty/fftreal/fftreal_wrapper.cpp
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU Lesser General Public License as
|
||||
** published by the Free Software Foundation, either version 2.1. This
|
||||
** program is distributed in the hope that it will be useful, but WITHOUT
|
||||
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
** for more details. You should have received a copy of the GNU General
|
||||
** Public License along with this program. If not, see
|
||||
** <http://www.gnu.org/licenses/>.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#include "fftreal_wrapper.h"
|
||||
|
||||
// FFTReal code generates quite a lot of 'unused parameter' compiler warnings,
|
||||
// which we suppress here in order to get a clean build output.
|
||||
#if defined Q_CC_MSVC
|
||||
# pragma warning(disable:4100)
|
||||
#elif defined Q_CC_GNU
|
||||
# pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
#elif defined Q_CC_MWERKS
|
||||
# pragma warning off (10182)
|
||||
#endif
|
||||
|
||||
#include "FFTRealFixLen.h"
|
||||
|
||||
class FFTRealWrapperPrivate {
|
||||
public:
|
||||
FFTRealFixLen<FFTLengthPowerOfTwo> m_fft;
|
||||
};
|
||||
|
||||
|
||||
FFTRealWrapper::FFTRealWrapper()
|
||||
: m_private(new FFTRealWrapperPrivate)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
FFTRealWrapper::~FFTRealWrapper()
|
||||
{
|
||||
delete m_private;
|
||||
}
|
||||
|
||||
void FFTRealWrapper::calculateFFT(DataType in[], const DataType out[])
|
||||
{
|
||||
m_private->m_fft.do_fft(in, out);
|
||||
}
|
||||
63
examples/multimedia/spectrum/3rdparty/fftreal/fftreal_wrapper.h
vendored
Normal file
63
examples/multimedia/spectrum/3rdparty/fftreal/fftreal_wrapper.h
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU Lesser General Public License as
|
||||
** published by the Free Software Foundation, either version 2.1. This
|
||||
** program is distributed in the hope that it will be useful, but WITHOUT
|
||||
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
** for more details. You should have received a copy of the GNU General
|
||||
** Public License along with this program. If not, see
|
||||
** <http://www.gnu.org/licenses/>.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef FFTREAL_WRAPPER_H
|
||||
#define FFTREAL_WRAPPER_H
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
|
||||
#if defined(FFTREAL_LIBRARY)
|
||||
# define FFTREAL_EXPORT Q_DECL_EXPORT
|
||||
#else
|
||||
# define FFTREAL_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
|
||||
class FFTRealWrapperPrivate;
|
||||
|
||||
// Each pass of the FFT processes 2^X samples, where X is the
|
||||
// number below.
|
||||
static const int FFTLengthPowerOfTwo = 12;
|
||||
|
||||
/**
|
||||
* Wrapper around the FFTRealFixLen template provided by the FFTReal
|
||||
* library
|
||||
*
|
||||
* This class instantiates a single instance of FFTRealFixLen, using
|
||||
* FFTLengthPowerOfTwo as the template parameter. It then exposes
|
||||
* FFTRealFixLen<FFTLengthPowerOfTwo>::do_fft via the calculateFFT
|
||||
* function, thereby allowing an application to dynamically link
|
||||
* against the FFTReal implementation.
|
||||
*
|
||||
* See http://ldesoras.free.fr/prod.html
|
||||
*/
|
||||
class FFTREAL_EXPORT FFTRealWrapper
|
||||
{
|
||||
public:
|
||||
FFTRealWrapper();
|
||||
~FFTRealWrapper();
|
||||
|
||||
typedef float DataType;
|
||||
void calculateFFT(DataType in[], const DataType out[]);
|
||||
|
||||
private:
|
||||
FFTRealWrapperPrivate* m_private;
|
||||
};
|
||||
|
||||
#endif // FFTREAL_WRAPPER_H
|
||||
|
||||
459
examples/multimedia/spectrum/3rdparty/fftreal/license.txt
vendored
Normal file
459
examples/multimedia/spectrum/3rdparty/fftreal/license.txt
vendored
Normal file
@@ -0,0 +1,459 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
242
examples/multimedia/spectrum/3rdparty/fftreal/readme.txt
vendored
Normal file
242
examples/multimedia/spectrum/3rdparty/fftreal/readme.txt
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
==============================================================================
|
||||
|
||||
FFTReal
|
||||
Version 2.00, 2005/10/18
|
||||
|
||||
Fourier transformation (FFT, IFFT) library specialised for real data
|
||||
Portable ISO C++
|
||||
|
||||
(c) Laurent de Soras <laurent.de.soras@club-internet.fr>
|
||||
Object Pascal port (c) Frederic Vanmol <frederic@fruityloops.com>
|
||||
|
||||
==============================================================================
|
||||
|
||||
|
||||
|
||||
1. Legal
|
||||
--------
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Check the file license.txt to get full information about the license.
|
||||
|
||||
|
||||
|
||||
2. Content
|
||||
----------
|
||||
|
||||
FFTReal is a library to compute Discrete Fourier Transforms (DFT) with the
|
||||
FFT algorithm (Fast Fourier Transform) on arrays of real numbers. It can
|
||||
also compute the inverse transform.
|
||||
|
||||
You should find in this package a lot of files ; some of them are of interest:
|
||||
- readme.txt: you are reading it
|
||||
- FFTReal.h: FFT, length fixed at run-time
|
||||
- FFTRealFixLen.h: FFT, length fixed at compile-time
|
||||
- FFTReal.pas: Pascal implementation (working but not up-to-date)
|
||||
- stopwatch directory
|
||||
|
||||
|
||||
|
||||
3. Using FFTReal
|
||||
----------------
|
||||
|
||||
Important - if you were using older versions of FFTReal (up to 1.03), some
|
||||
things have changed. FFTReal is now a template. Therefore use FFTReal<float>
|
||||
or FFTReal<double> in your code depending on the application datatype. The
|
||||
flt_t typedef has been removed.
|
||||
|
||||
You have two ways to use FFTReal. In the first way, the FFT has its length
|
||||
fixed at run-time, when the object is instanciated. It means that you have
|
||||
not to know the length when you write the code. This is the usual way of
|
||||
proceeding.
|
||||
|
||||
|
||||
3.1 FFTReal - Length fixed at run-time
|
||||
--------------------------------------
|
||||
|
||||
Just instanciate one time a FFTReal object. Specify the data type you want
|
||||
as template parameter (only floating point: float, double, long double or
|
||||
custom type). The constructor precompute a lot of things, so it may be a bit
|
||||
long. The parameter is the number of points used for the next FFTs. It must
|
||||
be a power of 2:
|
||||
|
||||
#include "FFTReal.h"
|
||||
...
|
||||
long len = 1024;
|
||||
...
|
||||
FFTReal <float> fft_object (len); // 1024-point FFT object constructed.
|
||||
|
||||
Then you can use this object to compute as many FFTs and IFFTs as you want.
|
||||
They will be computed very quickly because a lot of work has been done in the
|
||||
object construction.
|
||||
|
||||
float x [1024];
|
||||
float f [1024];
|
||||
|
||||
...
|
||||
fft_object.do_fft (f, x); // x (real) --FFT---> f (complex)
|
||||
...
|
||||
fft_object.do_ifft (f, x); // f (complex) --IFFT--> x (real)
|
||||
fft_object.rescale (x); // Post-scaling should be done after FFT+IFFT
|
||||
...
|
||||
|
||||
x [] and f [] are floating point number arrays. x [] is the real number
|
||||
sequence which we want to compute the FFT. f [] is the result, in the
|
||||
"frequency" domain. f has the same number of elements as x [], but f []
|
||||
elements are complex numbers. The routine uses some FFT properties to
|
||||
optimize memory and to reduce calculations: the transformaton of a real
|
||||
number sequence is a conjugate complex number sequence: F [k] = F [-k]*.
|
||||
|
||||
|
||||
3.2 FFTRealFixLen - Length fixed at compile-time
|
||||
------------------------------------------------
|
||||
|
||||
This class is significantly faster than the previous one, giving a speed
|
||||
gain between 50 and 100 %. The template parameter is the base-2 logarithm of
|
||||
the FFT length. The datatype is float; it can be changed by modifying the
|
||||
DataType typedef in FFTRealFixLenParam.h. As FFTReal class, it supports
|
||||
only floating-point types or equivalent.
|
||||
|
||||
To instanciate the object, just proceed as below:
|
||||
|
||||
#include "FFTRealFixLen.h"
|
||||
...
|
||||
FFTRealFixLen <10> fft_object; // 1024-point (2^10) FFT object constructed.
|
||||
|
||||
Use is similar as the one of FFTReal.
|
||||
|
||||
|
||||
3.3 Data organisation
|
||||
---------------------
|
||||
|
||||
Mathematically speaking, the formulas below show what does FFTReal:
|
||||
|
||||
do_fft() : f(k) = sum (p = 0, N-1, x(p) * exp (+j*2*pi*k*p/N))
|
||||
do_ifft(): x(k) = sum (p = 0, N-1, f(p) * exp (-j*2*pi*k*p/N))
|
||||
|
||||
Where j is the square root of -1. The formulas differ only by the sign of
|
||||
the exponential. When the sign is positive, the transform is called positive.
|
||||
Common formulas for Fourier transform are negative for the direct tranform and
|
||||
positive for the inverse one.
|
||||
|
||||
However in these formulas, f is an array of complex numbers and doesn't
|
||||
correspound exactly to the f[] array taken as function parameter. The
|
||||
following table shows how the f[] sequence is mapped onto the usable FFT
|
||||
coefficients (called bins):
|
||||
|
||||
FFTReal output | Positive FFT equiv. | Negative FFT equiv.
|
||||
---------------+-----------------------+-----------------------
|
||||
f [0] | Real (bin 0) | Real (bin 0)
|
||||
f [...] | Real (bin ...) | Real (bin ...)
|
||||
f [length/2] | Real (bin length/2) | Real (bin length/2)
|
||||
f [length/2+1] | Imag (bin 1) | -Imag (bin 1)
|
||||
f [...] | Imag (bin ...) | -Imag (bin ...)
|
||||
f [length-1] | Imag (bin length/2-1) | -Imag (bin length/2-1)
|
||||
|
||||
And FFT bins are distributed in f [] as above:
|
||||
|
||||
| | Positive FFT | Negative FFT
|
||||
Bin | Real part | imaginary part | imaginary part
|
||||
------------+----------------+-----------------+---------------
|
||||
0 | f [0] | 0 | 0
|
||||
1 | f [1] | f [length/2+1] | -f [length/2+1]
|
||||
... | f [...], | f [...] | -f [...]
|
||||
length/2-1 | f [length/2-1] | f [length-1] | -f [length-1]
|
||||
length/2 | f [length/2] | 0 | 0
|
||||
length/2+1 | f [length/2-1] | -f [length-1] | f [length-1]
|
||||
... | f [...] | -f [...] | f [...]
|
||||
length-1 | f [1] | -f [length/2+1] | f [length/2+1]
|
||||
|
||||
f [] coefficients have the same layout for FFT and IFFT functions. You may
|
||||
notice that scaling must be done if you want to retrieve x after FFT and IFFT.
|
||||
Actually, IFFT (FFT (x)) = x * length(x). This is a not a problem because
|
||||
most of the applications don't care about absolute values. Thus, the operation
|
||||
requires less calculation. If you want to use the FFT and IFFT to transform a
|
||||
signal, you have to apply post- (or pre-) processing yourself. Multiplying
|
||||
or dividing floating point numbers by a power of 2 doesn't generate extra
|
||||
computation noise.
|
||||
|
||||
|
||||
|
||||
4. Compilation and testing
|
||||
--------------------------
|
||||
|
||||
Drop the following files into your project or makefile:
|
||||
|
||||
Array.*
|
||||
def.h
|
||||
DynArray.*
|
||||
FFTReal*.cpp
|
||||
FFTReal*.h*
|
||||
OscSinCos.*
|
||||
|
||||
Other files are for testing purpose only, do not include them if you just need
|
||||
to use the library ; they are not needed to use FFTReal in your own programs.
|
||||
|
||||
FFTReal may be compiled in two versions: release and debug. Debug version
|
||||
has checks that could slow down the code. Define NDEBUG to set the Release
|
||||
mode. For example, the command line to compile the test bench on GCC would
|
||||
look like:
|
||||
|
||||
Debug mode:
|
||||
g++ -Wall -o fftreal_debug.exe *.cpp stopwatch/*.cpp
|
||||
|
||||
Release mode:
|
||||
g++ -Wall -o fftreal_release.exe -DNDEBUG -O3 *.cpp stopwatch/*.cpp
|
||||
|
||||
It may be tricky to compile the test bench because the speed tests use the
|
||||
stopwatch sub-library, which is not that cross-platform. If you encounter
|
||||
any problem that you cannot easily fix while compiling it, edit the file
|
||||
test_settings.h and un-define the speed test macro. Remove the stopwatch
|
||||
directory from your source file list, too.
|
||||
|
||||
If it's not done by default, you should activate the exception handling
|
||||
of your compiler to get the class memory-leak-safe. Thus, when a memory
|
||||
allocation fails (in the constructor), an exception is thrown and the entire
|
||||
object is safely destructed. It reduces the permanent error checking overhead
|
||||
in the client code. Also, the test bench requires Run-Time Type Information
|
||||
(RTTI) to be enabled in order to display the names of the tested classes -
|
||||
sometimes mangled, depending on the compiler.
|
||||
|
||||
The test bench may take a long time to compile, especially in Release mode,
|
||||
because a lot of recursive templates are instanciated.
|
||||
|
||||
|
||||
|
||||
5. History
|
||||
----------
|
||||
|
||||
v2.00 (2005.10.18)
|
||||
- Turned FFTReal class into template (data type as parameter)
|
||||
- Added FFTRealFixLen
|
||||
- Trigonometric tables are size-limited in order to preserve cache memory;
|
||||
over a given size, sin/cos functions are computed on the fly.
|
||||
- Better test bench for accuracy and speed
|
||||
|
||||
v1.03 (2001.06.15)
|
||||
- Thanks to Frederic Vanmol for the Pascal port (works with Delphi).
|
||||
- Documentation improvement
|
||||
|
||||
v1.02 (2001.03.25)
|
||||
- sqrt() is now precomputed when the object FFTReal is constructed, resulting
|
||||
in speed impovement for small size FFT.
|
||||
|
||||
v1.01 (2000)
|
||||
- Small modifications, I don't remember what.
|
||||
|
||||
v1.00 (1999.08.14)
|
||||
- First version released
|
||||
|
||||
285
examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/ClockCycleCounter.cpp
vendored
Normal file
285
examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/ClockCycleCounter.cpp
vendored
Normal file
@@ -0,0 +1,285 @@
|
||||
/*****************************************************************************
|
||||
|
||||
ClockCycleCounter.cpp
|
||||
Copyright (c) 2003 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma warning (1 : 4130) // "'operator' : logical operation on address of string constant"
|
||||
#pragma warning (1 : 4223) // "nonstandard extension used : non-lvalue array converted to pointer"
|
||||
#pragma warning (1 : 4705) // "statement has no effect"
|
||||
#pragma warning (1 : 4706) // "assignment within conditional expression"
|
||||
#pragma warning (4 : 4786) // "identifier was truncated to '255' characters in the debug information"
|
||||
#pragma warning (4 : 4800) // "forcing value to bool 'true' or 'false' (performance warning)"
|
||||
#pragma warning (4 : 4355) // "'this' : used in base member initializer list"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include "ClockCycleCounter.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
|
||||
namespace stopwatch
|
||||
{
|
||||
|
||||
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
Name: ctor
|
||||
Description:
|
||||
The first object constructed initialise global data. This first
|
||||
construction may be a bit slow.
|
||||
Throws: Nothing
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
ClockCycleCounter::ClockCycleCounter ()
|
||||
: _start_time (0)
|
||||
, _state (0)
|
||||
, _best_score (-1)
|
||||
{
|
||||
if (! _init_flag)
|
||||
{
|
||||
// Should be executed in this order
|
||||
compute_clk_mul ();
|
||||
compute_measure_time_total ();
|
||||
compute_measure_time_lap ();
|
||||
|
||||
// Restores object state
|
||||
_start_time = 0;
|
||||
_state = 0;
|
||||
_best_score = -1;
|
||||
|
||||
_init_flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
Name: get_time_total
|
||||
Description:
|
||||
Gives the time elapsed between the latest stop_lap() and start() calls.
|
||||
Returns:
|
||||
The duration, in clock cycles.
|
||||
Throws: Nothing
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
Int64 ClockCycleCounter::get_time_total () const
|
||||
{
|
||||
const Int64 duration = _state - _start_time;
|
||||
assert (duration >= 0);
|
||||
|
||||
const Int64 t = max (
|
||||
duration - _measure_time_total,
|
||||
static_cast <Int64> (0)
|
||||
);
|
||||
|
||||
return (t * _clk_mul);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
Name: get_time_best_lap
|
||||
Description:
|
||||
Gives the smallest time between two consecutive stop_lap() or between
|
||||
the stop_lap() and start(). The value is reset by a call to start().
|
||||
Call this function only after a stop_lap().
|
||||
The time is amputed from the duration of the stop_lap() call itself.
|
||||
Returns:
|
||||
The smallest duration, in clock cycles.
|
||||
Throws: Nothing
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
Int64 ClockCycleCounter::get_time_best_lap () const
|
||||
{
|
||||
assert (_best_score >= 0);
|
||||
|
||||
const Int64 t1 = max (
|
||||
_best_score - _measure_time_lap,
|
||||
static_cast <Int64> (0)
|
||||
);
|
||||
const Int64 t = min (t1, get_time_total ());
|
||||
|
||||
return (t * _clk_mul);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
#if defined (__MACOS__)
|
||||
|
||||
static inline double stopwatch_ClockCycleCounter_get_time_s ()
|
||||
{
|
||||
const Nanoseconds ns = AbsoluteToNanoseconds (UpTime ());
|
||||
|
||||
return (ns.hi * 4294967296e-9 + ns.lo * 1e-9);
|
||||
}
|
||||
|
||||
#endif // __MACOS__
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
Name: compute_clk_mul
|
||||
Description:
|
||||
This function, only for PowerPC/MacOS computers, computes the multiplier
|
||||
required to deduce clock cycles from the internal counter.
|
||||
Throws: Nothing
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
void ClockCycleCounter::compute_clk_mul ()
|
||||
{
|
||||
assert (! _init_flag);
|
||||
|
||||
#if defined (__MACOS__)
|
||||
|
||||
long clk_speed_mhz = CurrentProcessorSpeed ();
|
||||
const Int64 clk_speed =
|
||||
static_cast <Int64> (clk_speed_mhz) * (1000L*1000L);
|
||||
|
||||
const double start_time_s = stopwatch_ClockCycleCounter_get_time_s ();
|
||||
start ();
|
||||
|
||||
const double duration = 0.01; // Seconds
|
||||
while (stopwatch_ClockCycleCounter_get_time_s () - start_time_s < duration)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const double stop_time_s = stopwatch_ClockCycleCounter_get_time_s ();
|
||||
stop ();
|
||||
|
||||
const double diff_time_s = stop_time_s - start_time_s;
|
||||
const double nbr_cycles = diff_time_s * static_cast <double> (clk_speed);
|
||||
|
||||
const Int64 diff_time_c = _state - _start_time;
|
||||
const double clk_mul = nbr_cycles / static_cast <double> (diff_time_c);
|
||||
|
||||
_clk_mul = round_int (clk_mul);
|
||||
|
||||
#endif // __MACOS__
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ClockCycleCounter::compute_measure_time_total ()
|
||||
{
|
||||
start ();
|
||||
spend_time ();
|
||||
|
||||
Int64 best_result = 0x7FFFFFFFL; // Should be enough
|
||||
long nbr_tests = 100;
|
||||
for (long cnt = 0; cnt < nbr_tests; ++cnt)
|
||||
{
|
||||
start ();
|
||||
stop_lap ();
|
||||
const Int64 duration = _state - _start_time;
|
||||
best_result = min (best_result, duration);
|
||||
}
|
||||
|
||||
_measure_time_total = best_result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
Name: compute_measure_time_lap
|
||||
Description:
|
||||
Computes the duration of one stop_lap() call and store it. It will be used
|
||||
later to get the real duration of the measured operation (by substracting
|
||||
the measurement duration).
|
||||
Throws: Nothing
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
void ClockCycleCounter::compute_measure_time_lap ()
|
||||
{
|
||||
start ();
|
||||
spend_time ();
|
||||
|
||||
long nbr_tests = 10;
|
||||
for (long cnt = 0; cnt < nbr_tests; ++cnt)
|
||||
{
|
||||
stop_lap ();
|
||||
stop_lap ();
|
||||
stop_lap ();
|
||||
stop_lap ();
|
||||
}
|
||||
|
||||
_measure_time_lap = _best_score;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ClockCycleCounter::spend_time ()
|
||||
{
|
||||
const Int64 nbr_clocks = 500; // Number of clock cycles to spend
|
||||
|
||||
const Int64 start = read_clock_counter ();
|
||||
Int64 current;
|
||||
|
||||
do
|
||||
{
|
||||
current = read_clock_counter ();
|
||||
}
|
||||
while ((current - start) * _clk_mul < nbr_clocks);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Int64 ClockCycleCounter::_measure_time_total = 0;
|
||||
Int64 ClockCycleCounter::_measure_time_lap = 0;
|
||||
int ClockCycleCounter::_clk_mul = 1;
|
||||
bool ClockCycleCounter::_init_flag = false;
|
||||
|
||||
|
||||
} // namespace stopwatch
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
124
examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/ClockCycleCounter.h
vendored
Normal file
124
examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/ClockCycleCounter.h
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
/*****************************************************************************
|
||||
|
||||
ClockCycleCounter.h
|
||||
Copyright (c) 2003 Laurent de Soras
|
||||
|
||||
Instrumentation class, for accurate time interval measurement. You may have
|
||||
to modify the implementation to adapt it to your system and/or compiler.
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if ! defined (stopwatch_ClockCycleCounter_HEADER_INCLUDED)
|
||||
#define stopwatch_ClockCycleCounter_HEADER_INCLUDED
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma once
|
||||
#pragma warning (4 : 4250) // "Inherits via dominance."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include "def.h"
|
||||
#include "Int64.h"
|
||||
|
||||
|
||||
|
||||
namespace stopwatch
|
||||
{
|
||||
|
||||
|
||||
|
||||
class ClockCycleCounter
|
||||
{
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
public:
|
||||
|
||||
ClockCycleCounter ();
|
||||
|
||||
stopwatch_FORCEINLINE void
|
||||
start ();
|
||||
stopwatch_FORCEINLINE void
|
||||
stop_lap ();
|
||||
Int64 get_time_total () const;
|
||||
Int64 get_time_best_lap () const;
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
void compute_clk_mul ();
|
||||
void compute_measure_time_total ();
|
||||
void compute_measure_time_lap ();
|
||||
|
||||
static void spend_time ();
|
||||
static stopwatch_FORCEINLINE Int64
|
||||
read_clock_counter ();
|
||||
|
||||
Int64 _start_time;
|
||||
Int64 _state;
|
||||
Int64 _best_score;
|
||||
|
||||
static Int64 _measure_time_total;
|
||||
static Int64 _measure_time_lap;
|
||||
static int _clk_mul;
|
||||
static bool _init_flag;
|
||||
|
||||
|
||||
|
||||
/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
ClockCycleCounter (const ClockCycleCounter &other);
|
||||
ClockCycleCounter &
|
||||
operator = (const ClockCycleCounter &other);
|
||||
bool operator == (const ClockCycleCounter &other);
|
||||
bool operator != (const ClockCycleCounter &other);
|
||||
|
||||
}; // class ClockCycleCounter
|
||||
|
||||
|
||||
|
||||
} // namespace stopwatch
|
||||
|
||||
|
||||
|
||||
#include "ClockCycleCounter.hpp"
|
||||
|
||||
|
||||
|
||||
#endif // stopwatch_ClockCycleCounter_HEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
150
examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/ClockCycleCounter.hpp
vendored
Normal file
150
examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/ClockCycleCounter.hpp
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
/*****************************************************************************
|
||||
|
||||
ClockCycleCounter.hpp
|
||||
Copyright (c) 2003 Laurent de Soras
|
||||
|
||||
Please complete the definitions according to your compiler/architecture.
|
||||
It's not a big deal if it's not possible to get the clock count...
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if defined (stopwatch_ClockCycleCounter_CURRENT_CODEHEADER)
|
||||
#error Recursive inclusion of ClockCycleCounter code header.
|
||||
#endif
|
||||
#define stopwatch_ClockCycleCounter_CURRENT_CODEHEADER
|
||||
|
||||
#if ! defined (stopwatch_ClockCycleCounter_CODEHEADER_INCLUDED)
|
||||
#define stopwatch_ClockCycleCounter_CODEHEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include "fnc.h"
|
||||
|
||||
#include <climits>
|
||||
|
||||
|
||||
|
||||
namespace stopwatch
|
||||
{
|
||||
|
||||
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
Name: start
|
||||
Description:
|
||||
Starts the counter.
|
||||
Throws: Nothing
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
void ClockCycleCounter::start ()
|
||||
{
|
||||
_best_score = (static_cast <Int64> (1) << (sizeof (Int64) * CHAR_BIT - 2));
|
||||
const Int64 start_clock = read_clock_counter ();
|
||||
_start_time = start_clock;
|
||||
_state = start_clock - _best_score;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
Name: stop_lap
|
||||
Description:
|
||||
Captures the current time and updates the smallest duration between two
|
||||
consecutive calls to stop_lap() or the latest start().
|
||||
start() must have been called at least once before calling this function.
|
||||
Throws: Nothing
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
void ClockCycleCounter::stop_lap ()
|
||||
{
|
||||
const Int64 end_clock = read_clock_counter ();
|
||||
_best_score = min (end_clock - _state, _best_score);
|
||||
_state = end_clock;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
Int64 ClockCycleCounter::read_clock_counter ()
|
||||
{
|
||||
register Int64 clock_cnt;
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
|
||||
__asm
|
||||
{
|
||||
lea edi, clock_cnt
|
||||
rdtsc
|
||||
mov [edi ], eax
|
||||
mov [edi + 4], edx
|
||||
}
|
||||
|
||||
#elif defined (__GNUC__) && defined (__i386__)
|
||||
|
||||
__asm__ __volatile__ ("rdtsc" : "=A" (clock_cnt));
|
||||
|
||||
#elif (__MWERKS__) && defined (__POWERPC__)
|
||||
|
||||
asm
|
||||
{
|
||||
loop:
|
||||
mftbu clock_cnt@hiword
|
||||
mftb clock_cnt@loword
|
||||
mftbu r5
|
||||
cmpw clock_cnt@hiword,r5
|
||||
bne loop
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return (clock_cnt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace stopwatch
|
||||
|
||||
|
||||
|
||||
#endif // stopwatch_ClockCycleCounter_CODEHEADER_INCLUDED
|
||||
|
||||
#undef stopwatch_ClockCycleCounter_CURRENT_CODEHEADER
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
71
examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/Int64.h
vendored
Normal file
71
examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/Int64.h
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Int64.h
|
||||
Copyright (c) 2003 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if ! defined (stopwatch_Int64_HEADER_INCLUDED)
|
||||
#define stopwatch_Int64_HEADER_INCLUDED
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma once
|
||||
#pragma warning (4 : 4250) // "Inherits via dominance."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
namespace stopwatch
|
||||
{
|
||||
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
|
||||
typedef __int64 Int64;
|
||||
|
||||
#elif defined (__MWERKS__) || defined (__GNUC__)
|
||||
|
||||
typedef long long Int64;
|
||||
|
||||
#elif defined (__BEOS__)
|
||||
|
||||
typedef int64 Int64;
|
||||
|
||||
#else
|
||||
|
||||
#error No 64-bit integer type defined for this compiler !
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace stopwatch
|
||||
|
||||
|
||||
|
||||
#endif // stopwatch_Int64_HEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
101
examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/StopWatch.cpp
vendored
Normal file
101
examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/StopWatch.cpp
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
/*****************************************************************************
|
||||
|
||||
StopWatch.cpp
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma warning (1 : 4130) // "'operator' : logical operation on address of string constant"
|
||||
#pragma warning (1 : 4223) // "nonstandard extension used : non-lvalue array converted to pointer"
|
||||
#pragma warning (1 : 4705) // "statement has no effect"
|
||||
#pragma warning (1 : 4706) // "assignment within conditional expression"
|
||||
#pragma warning (4 : 4786) // "identifier was truncated to '255' characters in the debug information"
|
||||
#pragma warning (4 : 4800) // "forcing value to bool 'true' or 'false' (performance warning)"
|
||||
#pragma warning (4 : 4355) // "'this' : used in base member initializer list"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include "StopWatch.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
|
||||
namespace stopwatch
|
||||
{
|
||||
|
||||
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
StopWatch::StopWatch ()
|
||||
: _ccc ()
|
||||
, _nbr_laps (0)
|
||||
{
|
||||
// Nothing
|
||||
}
|
||||
|
||||
|
||||
|
||||
double StopWatch::get_time_total (Int64 nbr_op) const
|
||||
{
|
||||
assert (_nbr_laps > 0);
|
||||
assert (nbr_op > 0);
|
||||
|
||||
return (
|
||||
static_cast <double> (_ccc.get_time_total ())
|
||||
/ (static_cast <double> (nbr_op) * static_cast <double> (_nbr_laps))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
double StopWatch::get_time_best_lap (Int64 nbr_op) const
|
||||
{
|
||||
assert (nbr_op > 0);
|
||||
|
||||
return (
|
||||
static_cast <double> (_ccc.get_time_best_lap ())
|
||||
/ static_cast <double> (nbr_op)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
} // namespace stopwatch
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
110
examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/StopWatch.h
vendored
Normal file
110
examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/StopWatch.h
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
/*****************************************************************************
|
||||
|
||||
StopWatch.h
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
Utility class based on ClockCycleCounter to measure the unit time of a
|
||||
repeated operation.
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if ! defined (stopwatch_StopWatch_HEADER_INCLUDED)
|
||||
#define stopwatch_StopWatch_HEADER_INCLUDED
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma once
|
||||
#pragma warning (4 : 4250) // "Inherits via dominance."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
#include "ClockCycleCounter.h"
|
||||
|
||||
|
||||
|
||||
namespace stopwatch
|
||||
{
|
||||
|
||||
|
||||
|
||||
class StopWatch
|
||||
{
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
public:
|
||||
|
||||
StopWatch ();
|
||||
|
||||
stopwatch_FORCEINLINE void
|
||||
start ();
|
||||
stopwatch_FORCEINLINE void
|
||||
stop_lap ();
|
||||
|
||||
double get_time_total (Int64 nbr_op) const;
|
||||
double get_time_best_lap (Int64 nbr_op) const;
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
ClockCycleCounter
|
||||
_ccc;
|
||||
Int64 _nbr_laps;
|
||||
|
||||
|
||||
|
||||
/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
private:
|
||||
|
||||
StopWatch (const StopWatch &other);
|
||||
StopWatch & operator = (const StopWatch &other);
|
||||
bool operator == (const StopWatch &other);
|
||||
bool operator != (const StopWatch &other);
|
||||
|
||||
}; // class StopWatch
|
||||
|
||||
|
||||
|
||||
} // namespace stopwatch
|
||||
|
||||
|
||||
|
||||
#include "StopWatch.hpp"
|
||||
|
||||
|
||||
|
||||
#endif // stopwatch_StopWatch_HEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
83
examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/StopWatch.hpp
vendored
Normal file
83
examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/StopWatch.hpp
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
/*****************************************************************************
|
||||
|
||||
StopWatch.hpp
|
||||
Copyright (c) 2005 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if defined (stopwatch_StopWatch_CURRENT_CODEHEADER)
|
||||
#error Recursive inclusion of StopWatch code header.
|
||||
#endif
|
||||
#define stopwatch_StopWatch_CURRENT_CODEHEADER
|
||||
|
||||
#if ! defined (stopwatch_StopWatch_CODEHEADER_INCLUDED)
|
||||
#define stopwatch_StopWatch_CODEHEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
namespace stopwatch
|
||||
{
|
||||
|
||||
|
||||
|
||||
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
void StopWatch::start ()
|
||||
{
|
||||
_nbr_laps = 0;
|
||||
_ccc.start ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void StopWatch::stop_lap ()
|
||||
{
|
||||
_ccc.stop_lap ();
|
||||
++ _nbr_laps;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
} // namespace stopwatch
|
||||
|
||||
|
||||
|
||||
#endif // stopwatch_StopWatch_CODEHEADER_INCLUDED
|
||||
|
||||
#undef stopwatch_StopWatch_CURRENT_CODEHEADER
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
65
examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/def.h
vendored
Normal file
65
examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/def.h
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/*****************************************************************************
|
||||
|
||||
def.h
|
||||
Copyright (c) 2003 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if ! defined (stopwatch_def_HEADER_INCLUDED)
|
||||
#define stopwatch_def_HEADER_INCLUDED
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma once
|
||||
#pragma warning (4 : 4250) // "Inherits via dominance."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
namespace stopwatch
|
||||
{
|
||||
|
||||
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
|
||||
#define stopwatch_FORCEINLINE __forceinline
|
||||
|
||||
#else
|
||||
|
||||
#define stopwatch_FORCEINLINE inline
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
} // namespace stopwatch
|
||||
|
||||
|
||||
|
||||
#endif // stopwatch_def_HEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
67
examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/fnc.h
vendored
Normal file
67
examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/fnc.h
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
/*****************************************************************************
|
||||
|
||||
fnc.h
|
||||
Copyright (c) 2003 Laurent de Soras
|
||||
|
||||
--- Legal stuff ---
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*Tab=3***********************************************************************/
|
||||
|
||||
|
||||
|
||||
#if ! defined (stopwatch_fnc_HEADER_INCLUDED)
|
||||
#define stopwatch_fnc_HEADER_INCLUDED
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#pragma once
|
||||
#pragma warning (4 : 4250) // "Inherits via dominance."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
|
||||
|
||||
|
||||
namespace stopwatch
|
||||
{
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline T min (T a, T b);
|
||||
|
||||
template <typename T>
|
||||
inline T max (T a, T b);
|
||||
|
||||
inline int round_int (double x);
|
||||
|
||||
|
||||
|
||||
} // namespace rsp
|
||||
|
||||
|
||||
|
||||
#include "fnc.hpp"
|
||||
|
||||
|
||||
|
||||
#endif // stopwatch_fnc_HEADER_INCLUDED
|
||||
|
||||
|
||||
|
||||
/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user