mirror of https://github.com/PCSX2/pcsx2.git
3rdparty/soundtouch: Bump to v2.3.3
This commit is contained in:
parent
30e7de7555
commit
ebc3923b35
|
@ -15,8 +15,8 @@
|
||||||
|
|
||||||
<body class="normal">
|
<body class="normal">
|
||||||
<hr>
|
<hr>
|
||||||
<h1>SoundTouch audio processing library v2.3.1</h1>
|
<h1>SoundTouch audio processing library v2.3.3</h1>
|
||||||
<p class="normal">SoundTouch library Copyright © Olli Parviainen 2001-2021</p>
|
<p class="normal">SoundTouch library Copyright © Olli Parviainen 2001-2024</p>
|
||||||
<hr>
|
<hr>
|
||||||
<h2>1. Introduction </h2>
|
<h2>1. Introduction </h2>
|
||||||
<p>SoundTouch is an open-source audio processing library that allows
|
<p>SoundTouch is an open-source audio processing library that allows
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
<p>Author email: oparviai 'at' iki.fi </p>
|
<p>Author email: oparviai 'at' iki.fi </p>
|
||||||
<p>SoundTouch WWW page: <a href="http://soundtouch.surina.net">http://soundtouch.surina.net</a></p>
|
<p>SoundTouch WWW page: <a href="http://soundtouch.surina.net">http://soundtouch.surina.net</a></p>
|
||||||
<p>SoundTouch git repository: <a
|
<p>SoundTouch git repository: <a
|
||||||
href="https://gitlab.com/soundtouch/soundtouch.git">https://gitlab.com/soundtouch/soundtouch.git</a></p>
|
href="https://codeberg.org/soundtouch/soundtouch.git">https://codeberg.org/soundtouch/soundtouch.git</a></p>
|
||||||
<hr>
|
<hr>
|
||||||
<h2>2. Compiling SoundTouch</h2>
|
<h2>2. Compiling SoundTouch</h2>
|
||||||
<p>Before compiling, notice that you can choose the sample data format if it's
|
<p>Before compiling, notice that you can choose the sample data format if it's
|
||||||
|
@ -131,10 +131,12 @@
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<b>Compiling portable Shared Library / DLL version</b>
|
<b>Compiling portable Shared Library / DLL version</b>
|
||||||
<p> The GNU autotools compilation does not automatically create a shared-library version of
|
<p> The GNU autotools compilation automatically builds an additional dynamic-link version
|
||||||
SoundTouch (.so or .dll) that features position-independent code and C-language
|
of SoundTouch library that features position-independent code and "C"-style API that is
|
||||||
api that are more suitable for cross-language development than C++ libraries.</p>
|
more suitable for calling the SoundTouch routines from other programming languages.</p>
|
||||||
<p> Use script "make-gnu-dll-sh" to build a portable dynamic library version if such is desired.</p>
|
<p>This dynamic-link library is built under source/SoundTouchDLL directory, whose
|
||||||
|
subdirectories also comtain simple example apps that use the dynamic-link library.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h4><b>2.2.2 Compiling with cmake</b></h4>
|
<h4><b>2.2.2 Compiling with cmake</b></h4>
|
||||||
<p>'cmake' build scripts are provided as an alternative to the autotools toolchain.</p>
|
<p>'cmake' build scripts are provided as an alternative to the autotools toolchain.</p>
|
||||||
|
@ -145,6 +147,9 @@
|
||||||
cmake .
|
cmake .
|
||||||
make -j
|
make -j
|
||||||
make install</pre>
|
make install</pre>
|
||||||
|
<p>To list available build options:</p>
|
||||||
|
<pre>
|
||||||
|
cmake -LH</pre>
|
||||||
<p>To compile the additional portable Shared Library / DLL version with the native C-language API:</p>
|
<p>To compile the additional portable Shared Library / DLL version with the native C-language API:</p>
|
||||||
<pre>
|
<pre>
|
||||||
cmake . -DSOUNDTOUCH_DLL=ON
|
cmake . -DSOUNDTOUCH_DLL=ON
|
||||||
|
@ -448,7 +453,7 @@
|
||||||
<h2><a name="SoundStretch"></a>4. SoundStretch audio processing utility
|
<h2><a name="SoundStretch"></a>4. SoundStretch audio processing utility
|
||||||
</h2>
|
</h2>
|
||||||
<p>SoundStretch audio processing utility<br>
|
<p>SoundStretch audio processing utility<br>
|
||||||
Copyright (c) Olli Parviainen 2002-2015</p>
|
Copyright (c) Olli Parviainen 2002-2024</p>
|
||||||
<p>SoundStretch is a simple command-line application that can change
|
<p>SoundStretch is a simple command-line application that can change
|
||||||
tempo, pitch and playback rates of WAV sound files. This program is
|
tempo, pitch and playback rates of WAV sound files. This program is
|
||||||
intended primarily to demonstrate how the "SoundTouch" library can be
|
intended primarily to demonstrate how the "SoundTouch" library can be
|
||||||
|
@ -603,6 +608,18 @@
|
||||||
<hr>
|
<hr>
|
||||||
<h2>5. Change History</h2>
|
<h2>5. Change History</h2>
|
||||||
<h3>5.1. SoundTouch library Change History </h3>
|
<h3>5.1. SoundTouch library Change History </h3>
|
||||||
|
<p><b>2.3.3:</b></p>
|
||||||
|
<ul class="current">
|
||||||
|
<li>Fixing compiler warnings, maintenance fixes to make/build files for various systems
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p><b>2.3.2:</b></p>
|
||||||
|
<ul>
|
||||||
|
<li>Improve autotools makefiles to build the `SoundTouchDLL` dynamic-link link library with
|
||||||
|
C-style API. This library variation is easier to import and use from other programming
|
||||||
|
languages than the default C++ library.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
<p><b>2.3.1:</b></p>
|
<p><b>2.3.1:</b></p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Adjusted cmake build settings and header files that cmake installs</li>
|
<li>Adjusted cmake build settings and header files that cmake installs</li>
|
||||||
|
@ -865,11 +882,14 @@
|
||||||
<li> Initial release</li>
|
<li> Initial release</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h3>5.2. SoundStretch application Change History </h3>
|
<h3>5.2. SoundStretch application Change History </h3>
|
||||||
|
<p><b>2.3.3:</b></p>
|
||||||
|
<ul class="current_soundstretch">
|
||||||
|
<li>Added support for Asian / non-latin filenames in Windows. Gnu platform has supported them already earlier.</li>
|
||||||
|
</ul>
|
||||||
<p><b>1.9:</b></p>
|
<p><b>1.9:</b></p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Added support for WAV file 'fact' information chunk.</li>
|
<li>Added support for WAV file 'fact' information chunk.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p><b>1.7.0:</b></p>
|
<p><b>1.7.0:</b></p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Bugfixes in Wavfile: exception string formatting, avoid getLengthMs() integer
|
<li>Bugfixes in Wavfile: exception string formatting, avoid getLengthMs() integer
|
||||||
|
@ -966,6 +986,7 @@
|
||||||
<li> Michael Pruett</li>
|
<li> Michael Pruett</li>
|
||||||
<li> Rajeev Puran</li>
|
<li> Rajeev Puran</li>
|
||||||
<li> RJ Ryan</li>
|
<li> RJ Ryan</li>
|
||||||
|
<li> Serge Sans Paille</li>
|
||||||
<li> John Sheehy</li>
|
<li> John Sheehy</li>
|
||||||
<li> Tim Shuttleworth</li>
|
<li> Tim Shuttleworth</li>
|
||||||
<li> Albert Sirvent</li>
|
<li> Albert Sirvent</li>
|
||||||
|
|
|
@ -196,7 +196,7 @@ namespace soundtouch
|
||||||
/// - "values" receive array of beat detection strengths
|
/// - "values" receive array of beat detection strengths
|
||||||
/// - max_num indicates max.size of "pos" and "values" array.
|
/// - max_num indicates max.size of "pos" and "values" array.
|
||||||
///
|
///
|
||||||
/// You can query a suitable array sized by calling this with NULL in "pos" & "values".
|
/// You can query a suitable array sized by calling this with nullptr in "pos" & "values".
|
||||||
///
|
///
|
||||||
/// \return number of beats in the arrays.
|
/// \return number of beats in the arrays.
|
||||||
int getBeats(float *pos, float *strength, int max_num);
|
int getBeats(float *pos, float *strength, int max_num);
|
||||||
|
|
|
@ -88,11 +88,11 @@ public:
|
||||||
void moveSamples(FIFOSamplePipe &other ///< Other pipe instance where from the receive the data.
|
void moveSamples(FIFOSamplePipe &other ///< Other pipe instance where from the receive the data.
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int oNumSamples = other.numSamples();
|
const uint oNumSamples = other.numSamples();
|
||||||
|
|
||||||
putSamples(other.ptrBegin(), oNumSamples);
|
putSamples(other.ptrBegin(), oNumSamples);
|
||||||
other.receiveSamples(oNumSamples);
|
other.receiveSamples(oNumSamples);
|
||||||
};
|
}
|
||||||
|
|
||||||
/// Output samples from beginning of the sample buffer. Copies requested samples to
|
/// Output samples from beginning of the sample buffer. Copies requested samples to
|
||||||
/// output buffer and removes them from the sample buffer. If there are less than
|
/// output buffer and removes them from the sample buffer. If there are less than
|
||||||
|
@ -144,8 +144,8 @@ protected:
|
||||||
/// Sets output pipe.
|
/// Sets output pipe.
|
||||||
void setOutPipe(FIFOSamplePipe *pOutput)
|
void setOutPipe(FIFOSamplePipe *pOutput)
|
||||||
{
|
{
|
||||||
assert(output == NULL);
|
assert(output == nullptr);
|
||||||
assert(pOutput != NULL);
|
assert(pOutput != nullptr);
|
||||||
output = pOutput;
|
output = pOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ protected:
|
||||||
/// 'setOutPipe' function.
|
/// 'setOutPipe' function.
|
||||||
FIFOProcessor()
|
FIFOProcessor()
|
||||||
{
|
{
|
||||||
output = NULL;
|
output = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructor. Configures output pipe.
|
/// Constructor. Configures output pipe.
|
||||||
|
|
|
@ -72,10 +72,10 @@ namespace soundtouch
|
||||||
{
|
{
|
||||||
|
|
||||||
/// Soundtouch library version string
|
/// Soundtouch library version string
|
||||||
#define SOUNDTOUCH_VERSION "2.3.1"
|
#define SOUNDTOUCH_VERSION "2.3.3"
|
||||||
|
|
||||||
/// SoundTouch library version id
|
/// SoundTouch library version id
|
||||||
#define SOUNDTOUCH_VERSION_ID (20301)
|
#define SOUNDTOUCH_VERSION_ID (20303)
|
||||||
|
|
||||||
//
|
//
|
||||||
// Available setting IDs for the 'setSetting' & 'get_setting' functions:
|
// Available setting IDs for the 'setSetting' & 'get_setting' functions:
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///
|
||||||
|
/// Char type for SoundStretch
|
||||||
|
///
|
||||||
|
/// Author : Copyright (c) Olli Parviainen
|
||||||
|
/// Author e-mail : oparviai 'at' iki.fi
|
||||||
|
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// License :
|
||||||
|
//
|
||||||
|
// SoundTouch audio processing library
|
||||||
|
// Copyright (c) Olli Parviainen
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef SS_CHARTYPE_H
|
||||||
|
#define SS_CHARTYPE_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace soundstretch
|
||||||
|
{
|
||||||
|
#if _WIN32
|
||||||
|
// wide-char types for supporting non-latin file paths in Windows
|
||||||
|
using CHARTYPE = wchar_t;
|
||||||
|
using STRING = std::wstring;
|
||||||
|
#define STRING_CONST(x) (L"" x)
|
||||||
|
#else
|
||||||
|
// gnu platform can natively support UTF-8 paths using "char*" set
|
||||||
|
using CHARTYPE = char;
|
||||||
|
using STRING = std::string;
|
||||||
|
#define STRING_CONST(x) (x)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //SS_CHARTYPE_H
|
|
@ -42,17 +42,26 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <assert.h>
|
#include <cassert>
|
||||||
#include <limits.h>
|
#include <climits>
|
||||||
|
|
||||||
#include "WavFile.h"
|
#include "WavFile.h"
|
||||||
#include "STTypes.h"
|
#include "STTypes.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
namespace soundstretch
|
||||||
|
{
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
#define FOPEN(name, mode) _wfopen(name, STRING_CONST(mode))
|
||||||
|
#else
|
||||||
|
#define FOPEN(name, mode) fopen(name, mode)
|
||||||
|
#endif
|
||||||
|
|
||||||
static const char riffStr[] = "RIFF";
|
static const char riffStr[] = "RIFF";
|
||||||
static const char waveStr[] = "WAVE";
|
static const char waveStr[] = "WAVE";
|
||||||
static const char fmtStr[] = "fmt ";
|
static const char fmtStr[] = "fmt ";
|
||||||
static const char factStr[] = "fact";
|
static const char factStr[] = "fact";
|
||||||
static const char dataStr[] = "data";
|
static const char dataStr[] = "data";
|
||||||
|
|
||||||
|
@ -66,67 +75,67 @@ static const char dataStr[] = "data";
|
||||||
// while PowerPC of Mac's and many other RISC cpu's are big-endian.
|
// while PowerPC of Mac's and many other RISC cpu's are big-endian.
|
||||||
|
|
||||||
#ifdef BYTE_ORDER
|
#ifdef BYTE_ORDER
|
||||||
// In gcc compiler detect the byte order automatically
|
// In gcc compiler detect the byte order automatically
|
||||||
#if BYTE_ORDER == BIG_ENDIAN
|
#if BYTE_ORDER == BIG_ENDIAN
|
||||||
// big-endian platform.
|
// big-endian platform.
|
||||||
#define _BIG_ENDIAN_
|
#define _BIG_ENDIAN_
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _BIG_ENDIAN_
|
#ifdef _BIG_ENDIAN_
|
||||||
// big-endian CPU, swap bytes in 16 & 32 bit words
|
// big-endian CPU, swap bytes in 16 & 32 bit words
|
||||||
|
|
||||||
// helper-function to swap byte-order of 32bit integer
|
// helper-function to swap byte-order of 32bit integer
|
||||||
static inline int _swap32(int &dwData)
|
static inline int _swap32(int& dwData)
|
||||||
|
{
|
||||||
|
dwData = ((dwData >> 24) & 0x000000FF) |
|
||||||
|
((dwData >> 8) & 0x0000FF00) |
|
||||||
|
((dwData << 8) & 0x00FF0000) |
|
||||||
|
((dwData << 24) & 0xFF000000);
|
||||||
|
return dwData;
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper-function to swap byte-order of 16bit integer
|
||||||
|
static inline short _swap16(short& wData)
|
||||||
|
{
|
||||||
|
wData = ((wData >> 8) & 0x00FF) |
|
||||||
|
((wData << 8) & 0xFF00);
|
||||||
|
return wData;
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper-function to swap byte-order of buffer of 16bit integers
|
||||||
|
static inline void _swap16Buffer(short* pData, int numWords)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < numWords; i++)
|
||||||
{
|
{
|
||||||
dwData = ((dwData >> 24) & 0x000000FF) |
|
pData[i] = _swap16(pData[i]);
|
||||||
((dwData >> 8) & 0x0000FF00) |
|
|
||||||
((dwData << 8) & 0x00FF0000) |
|
|
||||||
((dwData << 24) & 0xFF000000);
|
|
||||||
return dwData;
|
|
||||||
}
|
|
||||||
|
|
||||||
// helper-function to swap byte-order of 16bit integer
|
|
||||||
static inline short _swap16(short &wData)
|
|
||||||
{
|
|
||||||
wData = ((wData >> 8) & 0x00FF) |
|
|
||||||
((wData << 8) & 0xFF00);
|
|
||||||
return wData;
|
|
||||||
}
|
|
||||||
|
|
||||||
// helper-function to swap byte-order of buffer of 16bit integers
|
|
||||||
static inline void _swap16Buffer(short *pData, int numWords)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < numWords; i ++)
|
|
||||||
{
|
|
||||||
pData[i] = _swap16(pData[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#else // BIG_ENDIAN
|
#else // BIG_ENDIAN
|
||||||
// little-endian CPU, WAV file is ok as such
|
// little-endian CPU, WAV file is ok as such
|
||||||
|
|
||||||
// dummy helper-function
|
// dummy helper-function
|
||||||
static inline int _swap32(int &dwData)
|
static inline int _swap32(int& dwData)
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
return dwData;
|
return dwData;
|
||||||
}
|
}
|
||||||
|
|
||||||
// dummy helper-function
|
// dummy helper-function
|
||||||
static inline short _swap16(short &wData)
|
static inline short _swap16(short& wData)
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
return wData;
|
return wData;
|
||||||
}
|
}
|
||||||
|
|
||||||
// dummy helper-function
|
// dummy helper-function
|
||||||
static inline void _swap16Buffer(short *pData, int numBytes)
|
static inline void _swap16Buffer(short*, int)
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BIG_ENDIAN
|
#endif // BIG_ENDIAN
|
||||||
|
|
||||||
|
@ -138,7 +147,7 @@ static const char dataStr[] = "data";
|
||||||
|
|
||||||
WavFileBase::WavFileBase()
|
WavFileBase::WavFileBase()
|
||||||
{
|
{
|
||||||
convBuff = NULL;
|
convBuff = nullptr;
|
||||||
convBuffSize = 0;
|
convBuffSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +160,7 @@ WavFileBase::~WavFileBase()
|
||||||
|
|
||||||
|
|
||||||
/// Get pointer to conversion buffer of at min. given size
|
/// Get pointer to conversion buffer of at min. given size
|
||||||
void *WavFileBase::getConvBuffer(int sizeBytes)
|
void* WavFileBase::getConvBuffer(int sizeBytes)
|
||||||
{
|
{
|
||||||
if (convBuffSize < sizeBytes)
|
if (convBuffSize < sizeBytes)
|
||||||
{
|
{
|
||||||
|
@ -169,32 +178,26 @@ void *WavFileBase::getConvBuffer(int sizeBytes)
|
||||||
// Class WavInFile
|
// Class WavInFile
|
||||||
//
|
//
|
||||||
|
|
||||||
WavInFile::WavInFile(const char *fileName)
|
WavInFile::WavInFile(const STRING& fileName)
|
||||||
{
|
{
|
||||||
// Try to open the file for reading
|
// Try to open the file for reading
|
||||||
fptr = fopen(fileName, "rb");
|
fptr = FOPEN(fileName.c_str(), "rb");
|
||||||
if (fptr == NULL)
|
if (fptr == nullptr)
|
||||||
{
|
{
|
||||||
// didn't succeed
|
ST_THROW_RT_ERROR("Error : Unable to open file for reading.");
|
||||||
string msg = "Error : Unable to open file \"";
|
|
||||||
msg += fileName;
|
|
||||||
msg += "\" for reading.";
|
|
||||||
ST_THROW_RT_ERROR(msg.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WavInFile::WavInFile(FILE *file)
|
WavInFile::WavInFile(FILE* file)
|
||||||
{
|
{
|
||||||
// Try to open the file for reading
|
// Try to open the file for reading
|
||||||
fptr = file;
|
fptr = file;
|
||||||
if (!file)
|
if (!file)
|
||||||
{
|
{
|
||||||
// didn't succeed
|
ST_THROW_RT_ERROR("Error : Unable to access input stream for reading");
|
||||||
string msg = "Error : Unable to access input stream for reading";
|
|
||||||
ST_THROW_RT_ERROR(msg.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
@ -213,17 +216,15 @@ void WavInFile::init()
|
||||||
hdrsOk = readWavHeaders();
|
hdrsOk = readWavHeaders();
|
||||||
if (hdrsOk != 0)
|
if (hdrsOk != 0)
|
||||||
{
|
{
|
||||||
// Something didn't match in the wav file headers
|
|
||||||
ST_THROW_RT_ERROR("Input file is corrupt or not a WAV file");
|
ST_THROW_RT_ERROR("Input file is corrupt or not a WAV file");
|
||||||
}
|
}
|
||||||
|
|
||||||
// sanity check for format parameters
|
// sanity check for format parameters
|
||||||
if ((header.format.channel_number < 1) || (header.format.channel_number > 9) ||
|
if ((header.format.channel_number < 1) || (header.format.channel_number > 9) ||
|
||||||
(header.format.sample_rate < 4000) || (header.format.sample_rate > 192000) ||
|
(header.format.sample_rate < 4000) || (header.format.sample_rate > 192000) ||
|
||||||
(header.format.byte_per_sample < 1) || (header.format.byte_per_sample > 320) ||
|
(header.format.byte_per_sample < 1) || (header.format.byte_per_sample > 320) ||
|
||||||
(header.format.bits_per_sample < 8) || (header.format.bits_per_sample > 32))
|
(header.format.bits_per_sample < 8) || (header.format.bits_per_sample > 32))
|
||||||
{
|
{
|
||||||
// Something didn't match in the wav file headers
|
|
||||||
ST_THROW_RT_ERROR("Error: Illegal wav file header format parameters.");
|
ST_THROW_RT_ERROR("Error: Illegal wav file header format parameters.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,7 +235,7 @@ void WavInFile::init()
|
||||||
WavInFile::~WavInFile()
|
WavInFile::~WavInFile()
|
||||||
{
|
{
|
||||||
if (fptr) fclose(fptr);
|
if (fptr) fclose(fptr);
|
||||||
fptr = NULL;
|
fptr = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -260,7 +261,7 @@ int WavInFile::checkCharTags() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int WavInFile::read(unsigned char *buffer, int maxElems)
|
int WavInFile::read(unsigned char* buffer, int maxElems)
|
||||||
{
|
{
|
||||||
int numBytes;
|
int numBytes;
|
||||||
uint afterDataRead;
|
uint afterDataRead;
|
||||||
|
@ -289,7 +290,7 @@ int WavInFile::read(unsigned char *buffer, int maxElems)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int WavInFile::read(short *buffer, int maxElems)
|
int WavInFile::read(short* buffer, int maxElems)
|
||||||
{
|
{
|
||||||
unsigned int afterDataRead;
|
unsigned int afterDataRead;
|
||||||
int numBytes;
|
int numBytes;
|
||||||
|
@ -298,53 +299,53 @@ int WavInFile::read(short *buffer, int maxElems)
|
||||||
assert(buffer);
|
assert(buffer);
|
||||||
switch (header.format.bits_per_sample)
|
switch (header.format.bits_per_sample)
|
||||||
{
|
{
|
||||||
case 8:
|
case 8:
|
||||||
{
|
{
|
||||||
// 8 bit format
|
// 8 bit format
|
||||||
unsigned char *temp = (unsigned char*)getConvBuffer(maxElems);
|
unsigned char* temp = (unsigned char*)getConvBuffer(maxElems);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
numElems = read(temp, maxElems);
|
numElems = read(temp, maxElems);
|
||||||
// convert from 8 to 16 bit
|
// convert from 8 to 16 bit
|
||||||
for (i = 0; i < numElems; i ++)
|
for (i = 0; i < numElems; i++)
|
||||||
{
|
{
|
||||||
buffer[i] = (short)(((short)temp[i] - 128) * 256);
|
buffer[i] = (short)(((short)temp[i] - 128) * 256);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 16:
|
||||||
|
{
|
||||||
|
// 16 bit format
|
||||||
|
|
||||||
|
assert(sizeof(short) == 2);
|
||||||
|
|
||||||
|
numBytes = maxElems * 2;
|
||||||
|
afterDataRead = dataRead + numBytes;
|
||||||
|
if (afterDataRead > header.data.data_len)
|
||||||
|
{
|
||||||
|
// Don't read more samples than are marked available in header
|
||||||
|
numBytes = (int)header.data.data_len - (int)dataRead;
|
||||||
|
assert(numBytes >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 16:
|
numBytes = (int)fread(buffer, 1, numBytes, fptr);
|
||||||
{
|
dataRead += numBytes;
|
||||||
// 16 bit format
|
numElems = numBytes / 2;
|
||||||
|
|
||||||
assert(sizeof(short) == 2);
|
// 16bit samples, swap byte order if necessary
|
||||||
|
_swap16Buffer((short*)buffer, numElems);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
numBytes = maxElems * 2;
|
default:
|
||||||
afterDataRead = dataRead + numBytes;
|
{
|
||||||
if (afterDataRead > header.data.data_len)
|
stringstream ss;
|
||||||
{
|
ss << "\nOnly 8/16 bit sample WAV files supported in integer compilation. Can't open WAV file with ";
|
||||||
// Don't read more samples than are marked available in header
|
ss << (int)header.format.bits_per_sample;
|
||||||
numBytes = (int)header.data.data_len - (int)dataRead;
|
ss << " bit sample format. ";
|
||||||
assert(numBytes >= 0);
|
ST_THROW_RT_ERROR(ss.str().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
numBytes = (int)fread(buffer, 1, numBytes, fptr);
|
|
||||||
dataRead += numBytes;
|
|
||||||
numElems = numBytes / 2;
|
|
||||||
|
|
||||||
// 16bit samples, swap byte order if necessary
|
|
||||||
_swap16Buffer((short *)buffer, numElems);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
stringstream ss;
|
|
||||||
ss << "\nOnly 8/16 bit sample WAV files supported in integer compilation. Can't open WAV file with ";
|
|
||||||
ss << (int)header.format.bits_per_sample;
|
|
||||||
ss << " bit sample format. ";
|
|
||||||
ST_THROW_RT_ERROR(ss.str().c_str());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return numElems;
|
return numElems;
|
||||||
|
@ -353,7 +354,7 @@ int WavInFile::read(short *buffer, int maxElems)
|
||||||
|
|
||||||
/// Read data in float format. Notice that when reading in float format
|
/// Read data in float format. Notice that when reading in float format
|
||||||
/// 8/16/24/32 bit sample formats are supported
|
/// 8/16/24/32 bit sample formats are supported
|
||||||
int WavInFile::read(float *buffer, int maxElems)
|
int WavInFile::read(float* buffer, int maxElems)
|
||||||
{
|
{
|
||||||
unsigned int afterDataRead;
|
unsigned int afterDataRead;
|
||||||
int numBytes;
|
int numBytes;
|
||||||
|
@ -382,7 +383,7 @@ int WavInFile::read(float *buffer, int maxElems)
|
||||||
}
|
}
|
||||||
|
|
||||||
// read raw data into temporary buffer
|
// read raw data into temporary buffer
|
||||||
char *temp = (char*)getConvBuffer(numBytes);
|
char* temp = (char*)getConvBuffer(numBytes);
|
||||||
numBytes = (int)fread(temp, 1, numBytes, fptr);
|
numBytes = (int)fread(temp, 1, numBytes, fptr);
|
||||||
dataRead += numBytes;
|
dataRead += numBytes;
|
||||||
|
|
||||||
|
@ -391,56 +392,56 @@ int WavInFile::read(float *buffer, int maxElems)
|
||||||
// swap byte ordert & convert to float, depending on sample format
|
// swap byte ordert & convert to float, depending on sample format
|
||||||
switch (bytesPerSample)
|
switch (bytesPerSample)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
|
{
|
||||||
|
unsigned char* temp2 = (unsigned char*)temp;
|
||||||
|
double conv = 1.0 / 128.0;
|
||||||
|
for (int i = 0; i < numElems; i++)
|
||||||
{
|
{
|
||||||
unsigned char *temp2 = (unsigned char*)temp;
|
buffer[i] = (float)(temp2[i] * conv - 1.0);
|
||||||
double conv = 1.0 / 128.0;
|
|
||||||
for (int i = 0; i < numElems; i ++)
|
|
||||||
{
|
|
||||||
buffer[i] = (float)(temp2[i] * conv - 1.0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
|
{
|
||||||
|
short* temp2 = (short*)temp;
|
||||||
|
double conv = 1.0 / 32768.0;
|
||||||
|
for (int i = 0; i < numElems; i++)
|
||||||
{
|
{
|
||||||
short *temp2 = (short*)temp;
|
short value = temp2[i];
|
||||||
double conv = 1.0 / 32768.0;
|
buffer[i] = (float)(_swap16(value) * conv);
|
||||||
for (int i = 0; i < numElems; i ++)
|
|
||||||
{
|
|
||||||
short value = temp2[i];
|
|
||||||
buffer[i] = (float)(_swap16(value) * conv);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
|
{
|
||||||
|
char* temp2 = (char*)temp;
|
||||||
|
double conv = 1.0 / 8388608.0;
|
||||||
|
for (int i = 0; i < numElems; i++)
|
||||||
{
|
{
|
||||||
char *temp2 = (char *)temp;
|
int value = *((int*)temp2);
|
||||||
double conv = 1.0 / 8388608.0;
|
value = _swap32(value) & 0x00ffffff; // take 24 bits
|
||||||
for (int i = 0; i < numElems; i ++)
|
value |= (value & 0x00800000) ? 0xff000000 : 0; // extend minus sign bits
|
||||||
{
|
buffer[i] = (float)(value * conv);
|
||||||
int value = *((int*)temp2);
|
temp2 += 3;
|
||||||
value = _swap32(value) & 0x00ffffff; // take 24 bits
|
|
||||||
value |= (value & 0x00800000) ? 0xff000000 : 0; // extend minus sign bits
|
|
||||||
buffer[i] = (float)(value * conv);
|
|
||||||
temp2 += 3;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
|
{
|
||||||
|
int* temp2 = (int*)temp;
|
||||||
|
double conv = 1.0 / 2147483648.0;
|
||||||
|
assert(sizeof(int) == 4);
|
||||||
|
for (int i = 0; i < numElems; i++)
|
||||||
{
|
{
|
||||||
int *temp2 = (int *)temp;
|
int value = temp2[i];
|
||||||
double conv = 1.0 / 2147483648.0;
|
buffer[i] = (float)(_swap32(value) * conv);
|
||||||
assert(sizeof(int) == 4);
|
|
||||||
for (int i = 0; i < numElems; i ++)
|
|
||||||
{
|
|
||||||
int value = temp2[i];
|
|
||||||
buffer[i] = (float)(_swap32(value) * conv);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return numElems;
|
return numElems;
|
||||||
|
@ -450,7 +451,7 @@ int WavInFile::read(float *buffer, int maxElems)
|
||||||
int WavInFile::eof() const
|
int WavInFile::eof() const
|
||||||
{
|
{
|
||||||
// return true if all data has been read or file eof has reached
|
// return true if all data has been read or file eof has reached
|
||||||
return (dataRead == header.data.data_len || feof(fptr));
|
return ((uint)dataRead == header.data.data_len || feof(fptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -462,7 +463,7 @@ static int isAlpha(char c)
|
||||||
|
|
||||||
|
|
||||||
// test if all characters are between a white space ' ' and little 'z'
|
// test if all characters are between a white space ' ' and little 'z'
|
||||||
static int isAlphaStr(const char *str)
|
static int isAlphaStr(const char* str)
|
||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
|
@ -470,7 +471,7 @@ static int isAlphaStr(const char *str)
|
||||||
while (c)
|
while (c)
|
||||||
{
|
{
|
||||||
if (isAlpha(c) == 0) return 0;
|
if (isAlpha(c) == 0) return 0;
|
||||||
str ++;
|
str++;
|
||||||
c = str[0];
|
c = str[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,7 +484,7 @@ int WavInFile::readRIFFBlock()
|
||||||
if (fread(&(header.riff), sizeof(WavRiff), 1, fptr) != 1) return -1;
|
if (fread(&(header.riff), sizeof(WavRiff), 1, fptr) != 1) return -1;
|
||||||
|
|
||||||
// swap 32bit data byte order if necessary
|
// swap 32bit data byte order if necessary
|
||||||
_swap32((int &)header.riff.package_len);
|
_swap32((int&)header.riff.package_len);
|
||||||
|
|
||||||
// header.riff.riff_char should equal to 'RIFF');
|
// header.riff.riff_char should equal to 'RIFF');
|
||||||
if (memcmp(riffStr, header.riff.riff_char, 4) != 0) return -1;
|
if (memcmp(riffStr, header.riff.riff_char, 4) != 0) return -1;
|
||||||
|
@ -500,7 +501,7 @@ int WavInFile::readHeaderBlock()
|
||||||
string sLabel;
|
string sLabel;
|
||||||
|
|
||||||
// lead label string
|
// lead label string
|
||||||
if (fread(label, 1, 4, fptr) !=4) return -1;
|
if (fread(label, 1, 4, fptr) != 4) return -1;
|
||||||
label[4] = 0;
|
label[4] = 0;
|
||||||
|
|
||||||
if (isAlphaStr(label) == 0) return -1; // not a valid label
|
if (isAlphaStr(label) == 0) return -1; // not a valid label
|
||||||
|
@ -536,12 +537,12 @@ int WavInFile::readHeaderBlock()
|
||||||
if (fread(&(header.format.fixed), nLen, 1, fptr) != 1) return -1;
|
if (fread(&(header.format.fixed), nLen, 1, fptr) != 1) return -1;
|
||||||
|
|
||||||
// swap byte order if necessary
|
// swap byte order if necessary
|
||||||
_swap16((short &)header.format.fixed); // short int fixed;
|
_swap16((short&)header.format.fixed); // short int fixed;
|
||||||
_swap16((short &)header.format.channel_number); // short int channel_number;
|
_swap16((short&)header.format.channel_number); // short int channel_number;
|
||||||
_swap32((int &)header.format.sample_rate); // int sample_rate;
|
_swap32((int&)header.format.sample_rate); // int sample_rate;
|
||||||
_swap32((int &)header.format.byte_rate); // int byte_rate;
|
_swap32((int&)header.format.byte_rate); // int byte_rate;
|
||||||
_swap16((short &)header.format.byte_per_sample); // short int byte_per_sample;
|
_swap16((short&)header.format.byte_per_sample); // short int byte_per_sample;
|
||||||
_swap16((short &)header.format.bits_per_sample); // short int bits_per_sample;
|
_swap16((short&)header.format.bits_per_sample); // short int bits_per_sample;
|
||||||
|
|
||||||
// if format_len is larger than expected, skip the extra data
|
// if format_len is larger than expected, skip the extra data
|
||||||
if (nDump > 0)
|
if (nDump > 0)
|
||||||
|
@ -581,7 +582,7 @@ int WavInFile::readHeaderBlock()
|
||||||
if (fread(&(header.fact.fact_sample_len), nLen, 1, fptr) != 1) return -1;
|
if (fread(&(header.fact.fact_sample_len), nLen, 1, fptr) != 1) return -1;
|
||||||
|
|
||||||
// swap byte order if necessary
|
// swap byte order if necessary
|
||||||
_swap32((int &)header.fact.fact_sample_len); // int sample_length;
|
_swap32((int&)header.fact.fact_sample_len); // int sample_length;
|
||||||
|
|
||||||
// if fact_len is larger than expected, skip the extra data
|
// if fact_len is larger than expected, skip the extra data
|
||||||
if (nDump > 0)
|
if (nDump > 0)
|
||||||
|
@ -598,7 +599,7 @@ int WavInFile::readHeaderBlock()
|
||||||
if (fread(&(header.data.data_len), sizeof(uint), 1, fptr) != 1) return -1;
|
if (fread(&(header.data.data_len), sizeof(uint), 1, fptr) != 1) return -1;
|
||||||
|
|
||||||
// swap byte order if necessary
|
// swap byte order if necessary
|
||||||
_swap32((int &)header.data.data_len);
|
_swap32((int&)header.data.data_len);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -611,7 +612,7 @@ int WavInFile::readHeaderBlock()
|
||||||
// read length
|
// read length
|
||||||
if (fread(&len, sizeof(len), 1, fptr) != 1) return -1;
|
if (fread(&len, sizeof(len), 1, fptr) != 1) return -1;
|
||||||
// scan through the block
|
// scan through the block
|
||||||
for (i = 0; i < len; i ++)
|
for (i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
if (fread(&temp, 1, 1, fptr) != 1) return -1;
|
if (fread(&temp, 1, 1, fptr) != 1) return -1;
|
||||||
if (feof(fptr)) return -1; // unexpected eof
|
if (feof(fptr)) return -1; // unexpected eof
|
||||||
|
@ -703,17 +704,13 @@ uint WavInFile::getElapsedMS() const
|
||||||
// Class WavOutFile
|
// Class WavOutFile
|
||||||
//
|
//
|
||||||
|
|
||||||
WavOutFile::WavOutFile(const char *fileName, int sampleRate, int bits, int channels)
|
WavOutFile::WavOutFile(const STRING& fileName, int sampleRate, int bits, int channels)
|
||||||
{
|
{
|
||||||
bytesWritten = 0;
|
bytesWritten = 0;
|
||||||
fptr = fopen(fileName, "wb");
|
fptr = FOPEN(fileName.c_str(), "wb");
|
||||||
if (fptr == NULL)
|
if (fptr == nullptr)
|
||||||
{
|
{
|
||||||
string msg = "Error : Unable to open file \"";
|
ST_THROW_RT_ERROR("Error : Unable to open file for writing.");
|
||||||
msg += fileName;
|
|
||||||
msg += "\" for writing.";
|
|
||||||
//pmsg = msg.c_str;
|
|
||||||
ST_THROW_RT_ERROR(msg.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fillInHeader(sampleRate, bits, channels);
|
fillInHeader(sampleRate, bits, channels);
|
||||||
|
@ -721,14 +718,13 @@ WavOutFile::WavOutFile(const char *fileName, int sampleRate, int bits, int chann
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WavOutFile::WavOutFile(FILE *file, int sampleRate, int bits, int channels)
|
WavOutFile::WavOutFile(FILE* file, int sampleRate, int bits, int channels)
|
||||||
{
|
{
|
||||||
bytesWritten = 0;
|
bytesWritten = 0;
|
||||||
fptr = file;
|
fptr = file;
|
||||||
if (fptr == NULL)
|
if (fptr == nullptr)
|
||||||
{
|
{
|
||||||
string msg = "Error : Unable to access output file stream.";
|
ST_THROW_RT_ERROR("Error : Unable to access output file stream.");
|
||||||
ST_THROW_RT_ERROR(msg.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fillInHeader(sampleRate, bits, channels);
|
fillInHeader(sampleRate, bits, channels);
|
||||||
|
@ -740,7 +736,7 @@ WavOutFile::~WavOutFile()
|
||||||
{
|
{
|
||||||
finishHeader();
|
finishHeader();
|
||||||
if (fptr) fclose(fptr);
|
if (fptr) fclose(fptr);
|
||||||
fptr = NULL;
|
fptr = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -801,17 +797,17 @@ void WavOutFile::writeHeader()
|
||||||
|
|
||||||
// swap byte order if necessary
|
// swap byte order if necessary
|
||||||
hdrTemp = header;
|
hdrTemp = header;
|
||||||
_swap32((int &)hdrTemp.riff.package_len);
|
_swap32((int&)hdrTemp.riff.package_len);
|
||||||
_swap32((int &)hdrTemp.format.format_len);
|
_swap32((int&)hdrTemp.format.format_len);
|
||||||
_swap16((short &)hdrTemp.format.fixed);
|
_swap16((short&)hdrTemp.format.fixed);
|
||||||
_swap16((short &)hdrTemp.format.channel_number);
|
_swap16((short&)hdrTemp.format.channel_number);
|
||||||
_swap32((int &)hdrTemp.format.sample_rate);
|
_swap32((int&)hdrTemp.format.sample_rate);
|
||||||
_swap32((int &)hdrTemp.format.byte_rate);
|
_swap32((int&)hdrTemp.format.byte_rate);
|
||||||
_swap16((short &)hdrTemp.format.byte_per_sample);
|
_swap16((short&)hdrTemp.format.byte_per_sample);
|
||||||
_swap16((short &)hdrTemp.format.bits_per_sample);
|
_swap16((short&)hdrTemp.format.bits_per_sample);
|
||||||
_swap32((int &)hdrTemp.data.data_len);
|
_swap32((int&)hdrTemp.data.data_len);
|
||||||
_swap32((int &)hdrTemp.fact.fact_len);
|
_swap32((int&)hdrTemp.fact.fact_len);
|
||||||
_swap32((int &)hdrTemp.fact.fact_sample_len);
|
_swap32((int&)hdrTemp.fact.fact_sample_len);
|
||||||
|
|
||||||
// write the supplemented header in the beginning of the file
|
// write the supplemented header in the beginning of the file
|
||||||
fseek(fptr, 0, SEEK_SET);
|
fseek(fptr, 0, SEEK_SET);
|
||||||
|
@ -826,7 +822,7 @@ void WavOutFile::writeHeader()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WavOutFile::write(const unsigned char *buffer, int numElems)
|
void WavOutFile::write(const unsigned char* buffer, int numElems)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
@ -846,7 +842,7 @@ void WavOutFile::write(const unsigned char *buffer, int numElems)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WavOutFile::write(const short *buffer, int numElems)
|
void WavOutFile::write(const short* buffer, int numElems)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
@ -855,47 +851,47 @@ void WavOutFile::write(const short *buffer, int numElems)
|
||||||
|
|
||||||
switch (header.format.bits_per_sample)
|
switch (header.format.bits_per_sample)
|
||||||
{
|
{
|
||||||
case 8:
|
case 8:
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned char* temp = (unsigned char*)getConvBuffer(numElems);
|
||||||
|
// convert from 16bit format to 8bit format
|
||||||
|
for (i = 0; i < numElems; i++)
|
||||||
{
|
{
|
||||||
int i;
|
temp[i] = (unsigned char)(buffer[i] / 256 + 128);
|
||||||
unsigned char *temp = (unsigned char *)getConvBuffer(numElems);
|
|
||||||
// convert from 16bit format to 8bit format
|
|
||||||
for (i = 0; i < numElems; i ++)
|
|
||||||
{
|
|
||||||
temp[i] = (unsigned char)(buffer[i] / 256 + 128);
|
|
||||||
}
|
|
||||||
// write in 8bit format
|
|
||||||
write(temp, numElems);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
// write in 8bit format
|
||||||
|
write(temp, numElems);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 16:
|
case 16:
|
||||||
|
{
|
||||||
|
// 16bit format
|
||||||
|
|
||||||
|
// use temp buffer to swap byte order if necessary
|
||||||
|
short* pTemp = (short*)getConvBuffer(numElems * sizeof(short));
|
||||||
|
memcpy(pTemp, buffer, (size_t)numElems * 2L);
|
||||||
|
_swap16Buffer(pTemp, numElems);
|
||||||
|
|
||||||
|
res = (int)fwrite(pTemp, 2, numElems, fptr);
|
||||||
|
|
||||||
|
if (res != numElems)
|
||||||
{
|
{
|
||||||
// 16bit format
|
ST_THROW_RT_ERROR("Error while writing to a wav file.");
|
||||||
|
|
||||||
// use temp buffer to swap byte order if necessary
|
|
||||||
short *pTemp = (short *)getConvBuffer(numElems * sizeof(short));
|
|
||||||
memcpy(pTemp, buffer, numElems * 2);
|
|
||||||
_swap16Buffer(pTemp, numElems);
|
|
||||||
|
|
||||||
res = (int)fwrite(pTemp, 2, numElems, fptr);
|
|
||||||
|
|
||||||
if (res != numElems)
|
|
||||||
{
|
|
||||||
ST_THROW_RT_ERROR("Error while writing to a wav file.");
|
|
||||||
}
|
|
||||||
bytesWritten += 2 * numElems;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
bytesWritten += 2 * numElems;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss << "\nOnly 8/16 bit sample WAV files supported in integer compilation. Can't open WAV file with ";
|
ss << "\nOnly 8/16 bit sample WAV files supported in integer compilation. Can't open WAV file with ";
|
||||||
ss << (int)header.format.bits_per_sample;
|
ss << (int)header.format.bits_per_sample;
|
||||||
ss << " bit sample format. ";
|
ss << " bit sample format. ";
|
||||||
ST_THROW_RT_ERROR(ss.str().c_str());
|
ST_THROW_RT_ERROR(ss.str().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -915,7 +911,7 @@ inline int saturate(float fvalue, float minval, float maxval)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WavOutFile::write(const float *buffer, int numElems)
|
void WavOutFile::write(const float* buffer, int numElems)
|
||||||
{
|
{
|
||||||
int numBytes;
|
int numBytes;
|
||||||
int bytesPerSample;
|
int bytesPerSample;
|
||||||
|
@ -924,56 +920,56 @@ void WavOutFile::write(const float *buffer, int numElems)
|
||||||
|
|
||||||
bytesPerSample = header.format.bits_per_sample / 8;
|
bytesPerSample = header.format.bits_per_sample / 8;
|
||||||
numBytes = numElems * bytesPerSample;
|
numBytes = numElems * bytesPerSample;
|
||||||
void *temp = getConvBuffer(numBytes + 7); // round bit up to avoid buffer overrun with 24bit-value assignment
|
void* temp = getConvBuffer(numBytes + 7); // round bit up to avoid buffer overrun with 24bit-value assignment
|
||||||
|
|
||||||
switch (bytesPerSample)
|
switch (bytesPerSample)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
|
{
|
||||||
|
unsigned char* temp2 = (unsigned char*)temp;
|
||||||
|
for (int i = 0; i < numElems; i++)
|
||||||
{
|
{
|
||||||
unsigned char *temp2 = (unsigned char *)temp;
|
temp2[i] = (unsigned char)saturate(buffer[i] * 128.0f + 128.0f, 0.0f, 255.0f);
|
||||||
for (int i = 0; i < numElems; i ++)
|
|
||||||
{
|
|
||||||
temp2[i] = (unsigned char)saturate(buffer[i] * 128.0f + 128.0f, 0.0f, 255.0f);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
|
{
|
||||||
|
short* temp2 = (short*)temp;
|
||||||
|
for (int i = 0; i < numElems; i++)
|
||||||
{
|
{
|
||||||
short *temp2 = (short *)temp;
|
short value = (short)saturate(buffer[i] * 32768.0f, -32768.0f, 32767.0f);
|
||||||
for (int i = 0; i < numElems; i ++)
|
temp2[i] = _swap16(value);
|
||||||
{
|
|
||||||
short value = (short)saturate(buffer[i] * 32768.0f, -32768.0f, 32767.0f);
|
|
||||||
temp2[i] = _swap16(value);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
|
{
|
||||||
|
char* temp2 = (char*)temp;
|
||||||
|
for (int i = 0; i < numElems; i++)
|
||||||
{
|
{
|
||||||
char *temp2 = (char *)temp;
|
int value = saturate(buffer[i] * 8388608.0f, -8388608.0f, 8388607.0f);
|
||||||
for (int i = 0; i < numElems; i ++)
|
*((int*)temp2) = _swap32(value);
|
||||||
{
|
temp2 += 3;
|
||||||
int value = saturate(buffer[i] * 8388608.0f, -8388608.0f, 8388607.0f);
|
|
||||||
*((int*)temp2) = _swap32(value);
|
|
||||||
temp2 += 3;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
|
{
|
||||||
|
int* temp2 = (int*)temp;
|
||||||
|
for (int i = 0; i < numElems; i++)
|
||||||
{
|
{
|
||||||
int *temp2 = (int *)temp;
|
int value = saturate(buffer[i] * 2147483648.0f, -2147483648.0f, 2147483647.0f);
|
||||||
for (int i = 0; i < numElems; i ++)
|
temp2[i] = _swap32(value);
|
||||||
{
|
|
||||||
int value = saturate(buffer[i] * 2147483648.0f, -2147483648.0f, 2147483647.0f);
|
|
||||||
temp2[i] = _swap32(value);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = (int)fwrite(temp, 1, numBytes, fptr);
|
int res = (int)fwrite(temp, 1, numBytes, fptr);
|
||||||
|
@ -984,3 +980,5 @@ void WavOutFile::write(const float *buffer, int numElems)
|
||||||
}
|
}
|
||||||
bytesWritten += numBytes;
|
bytesWritten += numBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -40,7 +40,12 @@
|
||||||
#ifndef WAVFILE_H
|
#ifndef WAVFILE_H
|
||||||
#define WAVFILE_H
|
#define WAVFILE_H
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <cstdio>
|
||||||
|
#include <string>
|
||||||
|
#include "SS_CharTypes.h"
|
||||||
|
|
||||||
|
namespace soundstretch
|
||||||
|
{
|
||||||
|
|
||||||
#ifndef uint
|
#ifndef uint
|
||||||
typedef unsigned int uint;
|
typedef unsigned int uint;
|
||||||
|
@ -118,9 +123,6 @@ private:
|
||||||
/// File pointer.
|
/// File pointer.
|
||||||
FILE *fptr;
|
FILE *fptr;
|
||||||
|
|
||||||
/// Position within the audio stream
|
|
||||||
long position;
|
|
||||||
|
|
||||||
/// Counter of how many bytes of sample data have been read from the file.
|
/// Counter of how many bytes of sample data have been read from the file.
|
||||||
long dataRead;
|
long dataRead;
|
||||||
|
|
||||||
|
@ -148,7 +150,7 @@ private:
|
||||||
public:
|
public:
|
||||||
/// Constructor: Opens the given WAV file. If the file can't be opened,
|
/// Constructor: Opens the given WAV file. If the file can't be opened,
|
||||||
/// throws 'runtime_error' exception.
|
/// throws 'runtime_error' exception.
|
||||||
WavInFile(const char *filename);
|
WavInFile(const STRING& filename);
|
||||||
|
|
||||||
WavInFile(FILE *file);
|
WavInFile(FILE *file);
|
||||||
|
|
||||||
|
@ -244,7 +246,7 @@ private:
|
||||||
public:
|
public:
|
||||||
/// Constructor: Creates a new WAV file. Throws a 'runtime_error' exception
|
/// Constructor: Creates a new WAV file. Throws a 'runtime_error' exception
|
||||||
/// if file creation fails.
|
/// if file creation fails.
|
||||||
WavOutFile(const char *fileName, ///< Filename
|
WavOutFile(const STRING& fileName, ///< Filename
|
||||||
int sampleRate, ///< Sample rate (e.g. 44100 etc)
|
int sampleRate, ///< Sample rate (e.g. 44100 etc)
|
||||||
int bits, ///< Bits per sample (8 or 16 bits)
|
int bits, ///< Bits per sample (8 or 16 bits)
|
||||||
int channels ///< Number of channels (1=mono, 2=stereo)
|
int channels ///< Number of channels (1=mono, 2=stereo)
|
||||||
|
@ -274,4 +276,6 @@ public:
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -54,7 +54,7 @@ using namespace soundtouch;
|
||||||
static void _DEBUG_SAVE_AAFIR_COEFFS(SAMPLETYPE *coeffs, int len)
|
static void _DEBUG_SAVE_AAFIR_COEFFS(SAMPLETYPE *coeffs, int len)
|
||||||
{
|
{
|
||||||
FILE *fptr = fopen("aa_filter_coeffs.txt", "wt");
|
FILE *fptr = fopen("aa_filter_coeffs.txt", "wt");
|
||||||
if (fptr == NULL) return;
|
if (fptr == nullptr) return;
|
||||||
|
|
||||||
for (int i = 0; i < len; i ++)
|
for (int i = 0; i < len; i ++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -376,8 +376,6 @@ void BPMDetect::updateBeatPos(int process_samples)
|
||||||
// detect beats
|
// detect beats
|
||||||
for (int i = 0; i < skipstep; i++)
|
for (int i = 0; i < skipstep; i++)
|
||||||
{
|
{
|
||||||
LONG_SAMPLETYPE max = 0;
|
|
||||||
|
|
||||||
float sum = beatcorr_ringbuff[beatcorr_ringbuffpos];
|
float sum = beatcorr_ringbuff[beatcorr_ringbuffpos];
|
||||||
sum -= beat_lpf.update(sum);
|
sum -= beat_lpf.update(sum);
|
||||||
|
|
||||||
|
@ -556,13 +554,13 @@ float BPMDetect::getBpm()
|
||||||
/// - "values" receive array of beat detection strengths
|
/// - "values" receive array of beat detection strengths
|
||||||
/// - max_num indicates max.size of "pos" and "values" array.
|
/// - max_num indicates max.size of "pos" and "values" array.
|
||||||
///
|
///
|
||||||
/// You can query a suitable array sized by calling this with NULL in "pos" & "values".
|
/// You can query a suitable array sized by calling this with nullptr in "pos" & "values".
|
||||||
///
|
///
|
||||||
/// \return number of beats in the arrays.
|
/// \return number of beats in the arrays.
|
||||||
int BPMDetect::getBeats(float *pos, float *values, int max_num)
|
int BPMDetect::getBeats(float *pos, float *values, int max_num)
|
||||||
{
|
{
|
||||||
int num = (int)beats.size();
|
int num = (int)beats.size();
|
||||||
if ((!pos) || (!values)) return num; // pos or values NULL, return just size
|
if ((!pos) || (!values)) return num; // pos or values nullptr, return just size
|
||||||
|
|
||||||
for (int i = 0; (i < num) && (i < max_num); i++)
|
for (int i = 0; (i < num) && (i < max_num); i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -50,8 +50,8 @@ FIFOSampleBuffer::FIFOSampleBuffer(int numChannels)
|
||||||
{
|
{
|
||||||
assert(numChannels > 0);
|
assert(numChannels > 0);
|
||||||
sizeInBytes = 0; // reasonable initial value
|
sizeInBytes = 0; // reasonable initial value
|
||||||
buffer = NULL;
|
buffer = nullptr;
|
||||||
bufferUnaligned = NULL;
|
bufferUnaligned = nullptr;
|
||||||
samplesInBuffer = 0;
|
samplesInBuffer = 0;
|
||||||
bufferPos = 0;
|
bufferPos = 0;
|
||||||
channels = (uint)numChannels;
|
channels = (uint)numChannels;
|
||||||
|
@ -63,8 +63,8 @@ FIFOSampleBuffer::FIFOSampleBuffer(int numChannels)
|
||||||
FIFOSampleBuffer::~FIFOSampleBuffer()
|
FIFOSampleBuffer::~FIFOSampleBuffer()
|
||||||
{
|
{
|
||||||
delete[] bufferUnaligned;
|
delete[] bufferUnaligned;
|
||||||
bufferUnaligned = NULL;
|
bufferUnaligned = nullptr;
|
||||||
buffer = NULL;
|
buffer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ void FIFOSampleBuffer::ensureCapacity(uint capacityRequirement)
|
||||||
sizeInBytes = (capacityRequirement * channels * sizeof(SAMPLETYPE) + 4095) & (uint)-4096;
|
sizeInBytes = (capacityRequirement * channels * sizeof(SAMPLETYPE) + 4095) & (uint)-4096;
|
||||||
assert(sizeInBytes % 2 == 0);
|
assert(sizeInBytes % 2 == 0);
|
||||||
tempUnaligned = new SAMPLETYPE[sizeInBytes / sizeof(SAMPLETYPE) + 16 / sizeof(SAMPLETYPE)];
|
tempUnaligned = new SAMPLETYPE[sizeInBytes / sizeof(SAMPLETYPE) + 16 / sizeof(SAMPLETYPE)];
|
||||||
if (tempUnaligned == NULL)
|
if (tempUnaligned == nullptr)
|
||||||
{
|
{
|
||||||
ST_THROW_RT_ERROR("Couldn't allocate memory!\n");
|
ST_THROW_RT_ERROR("Couldn't allocate memory!\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,8 +59,8 @@ FIRFilter::FIRFilter()
|
||||||
resultDivider = 0;
|
resultDivider = 0;
|
||||||
length = 0;
|
length = 0;
|
||||||
lengthDiv8 = 0;
|
lengthDiv8 = 0;
|
||||||
filterCoeffs = NULL;
|
filterCoeffs = nullptr;
|
||||||
filterCoeffsStereo = NULL;
|
filterCoeffsStereo = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,15 +75,11 @@ FIRFilter::~FIRFilter()
|
||||||
uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) const
|
uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) const
|
||||||
{
|
{
|
||||||
int j, end;
|
int j, end;
|
||||||
#ifdef SOUNDTOUCH_FLOAT_SAMPLES
|
|
||||||
// when using floating point samples, use a scaler instead of a divider
|
|
||||||
// because division is much slower operation than multiplying.
|
|
||||||
double dScaler = 1.0 / (double)resultDivider;
|
|
||||||
#endif
|
|
||||||
// hint compiler autovectorization that loop length is divisible by 8
|
// hint compiler autovectorization that loop length is divisible by 8
|
||||||
int ilength = length & -8;
|
uint ilength = length & -8;
|
||||||
|
|
||||||
assert((length != 0) && (length == ilength) && (src != NULL) && (dest != NULL) && (filterCoeffs != NULL));
|
assert((length != 0) && (length == ilength) && (src != nullptr) && (dest != nullptr) && (filterCoeffs != nullptr));
|
||||||
|
assert(numSamples > ilength);
|
||||||
|
|
||||||
end = 2 * (numSamples - ilength);
|
end = 2 * (numSamples - ilength);
|
||||||
|
|
||||||
|
@ -96,7 +92,7 @@ uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, ui
|
||||||
suml = sumr = 0;
|
suml = sumr = 0;
|
||||||
ptr = src + j;
|
ptr = src + j;
|
||||||
|
|
||||||
for (int i = 0; i < ilength; i ++)
|
for (uint i = 0; i < ilength; i ++)
|
||||||
{
|
{
|
||||||
suml += ptr[2 * i] * filterCoeffsStereo[2 * i];
|
suml += ptr[2 * i] * filterCoeffsStereo[2 * i];
|
||||||
sumr += ptr[2 * i + 1] * filterCoeffsStereo[2 * i + 1];
|
sumr += ptr[2 * i + 1] * filterCoeffsStereo[2 * i + 1];
|
||||||
|
@ -121,11 +117,6 @@ uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, ui
|
||||||
uint FIRFilter::evaluateFilterMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) const
|
uint FIRFilter::evaluateFilterMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) const
|
||||||
{
|
{
|
||||||
int j, end;
|
int j, end;
|
||||||
#ifdef SOUNDTOUCH_FLOAT_SAMPLES
|
|
||||||
// when using floating point samples, use a scaler instead of a divider
|
|
||||||
// because division is much slower operation than multiplying.
|
|
||||||
double dScaler = 1.0 / (double)resultDivider;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// hint compiler autovectorization that loop length is divisible by 8
|
// hint compiler autovectorization that loop length is divisible by 8
|
||||||
int ilength = length & -8;
|
int ilength = length & -8;
|
||||||
|
@ -160,16 +151,10 @@ uint FIRFilter::evaluateFilterMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uin
|
||||||
{
|
{
|
||||||
int j, end;
|
int j, end;
|
||||||
|
|
||||||
#ifdef SOUNDTOUCH_FLOAT_SAMPLES
|
|
||||||
// when using floating point samples, use a scaler instead of a divider
|
|
||||||
// because division is much slower operation than multiplying.
|
|
||||||
double dScaler = 1.0 / (double)resultDivider;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
assert(length != 0);
|
assert(length != 0);
|
||||||
assert(src != NULL);
|
assert(src != nullptr);
|
||||||
assert(dest != NULL);
|
assert(dest != nullptr);
|
||||||
assert(filterCoeffs != NULL);
|
assert(filterCoeffs != nullptr);
|
||||||
assert(numChannels < 16);
|
assert(numChannels < 16);
|
||||||
|
|
||||||
// hint compiler autovectorization that loop length is divisible by 8
|
// hint compiler autovectorization that loop length is divisible by 8
|
||||||
|
@ -288,7 +273,7 @@ uint FIRFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSample
|
||||||
|
|
||||||
// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
||||||
// depending on if we've a MMX-capable CPU available or not.
|
// depending on if we've a MMX-capable CPU available or not.
|
||||||
void * FIRFilter::operator new(size_t s)
|
void * FIRFilter::operator new(size_t)
|
||||||
{
|
{
|
||||||
// Notice! don't use "new FIRFilter" directly, use "newInstance" to create a new instance instead!
|
// Notice! don't use "new FIRFilter" directly, use "newInstance" to create a new instance instead!
|
||||||
ST_THROW_RT_ERROR("Error in FIRFilter::new: Don't use 'new FIRFilter', use 'newInstance' member instead!");
|
ST_THROW_RT_ERROR("Error in FIRFilter::new: Don't use 'new FIRFilter', use 'newInstance' member instead!");
|
||||||
|
@ -301,6 +286,7 @@ FIRFilter * FIRFilter::newInstance()
|
||||||
uint uExtensions;
|
uint uExtensions;
|
||||||
|
|
||||||
uExtensions = detectCPUextensions();
|
uExtensions = detectCPUextensions();
|
||||||
|
(void)uExtensions;
|
||||||
|
|
||||||
// Check if MMX/SSE instruction set extensions supported by CPU
|
// Check if MMX/SSE instruction set extensions supported by CPU
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
namespace soundtouch
|
namespace soundtouch
|
||||||
{
|
{
|
||||||
|
|
||||||
class InterpolateCubic final : public TransposerBase
|
class InterpolateCubic : public TransposerBase
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
virtual int transposeMono(SAMPLETYPE *dest,
|
virtual int transposeMono(SAMPLETYPE *dest,
|
||||||
|
@ -58,7 +58,7 @@ public:
|
||||||
|
|
||||||
virtual void resetRegisters() override;
|
virtual void resetRegisters() override;
|
||||||
|
|
||||||
int getLatency() const override
|
virtual int getLatency() const override
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace soundtouch
|
||||||
{
|
{
|
||||||
|
|
||||||
/// Linear transposer class that uses integer arithmetic
|
/// Linear transposer class that uses integer arithmetic
|
||||||
class InterpolateLinearInteger final : public TransposerBase
|
class InterpolateLinearInteger : public TransposerBase
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
int iFract;
|
int iFract;
|
||||||
|
@ -61,7 +61,7 @@ public:
|
||||||
|
|
||||||
virtual void resetRegisters() override;
|
virtual void resetRegisters() override;
|
||||||
|
|
||||||
int getLatency() const override
|
virtual int getLatency() const override
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -69,25 +69,25 @@ public:
|
||||||
|
|
||||||
|
|
||||||
/// Linear transposer class that uses floating point arithmetic
|
/// Linear transposer class that uses floating point arithmetic
|
||||||
class InterpolateLinearFloat final : public TransposerBase
|
class InterpolateLinearFloat : public TransposerBase
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
double fract;
|
double fract;
|
||||||
|
|
||||||
virtual int transposeMono(SAMPLETYPE *dest,
|
virtual int transposeMono(SAMPLETYPE *dest,
|
||||||
const SAMPLETYPE *src,
|
const SAMPLETYPE *src,
|
||||||
int &srcSamples) override;
|
int &srcSamples);
|
||||||
virtual int transposeStereo(SAMPLETYPE *dest,
|
virtual int transposeStereo(SAMPLETYPE *dest,
|
||||||
const SAMPLETYPE *src,
|
const SAMPLETYPE *src,
|
||||||
int &srcSamples) override;
|
int &srcSamples);
|
||||||
virtual int transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples) override;
|
virtual int transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InterpolateLinearFloat();
|
InterpolateLinearFloat();
|
||||||
|
|
||||||
void resetRegisters() override;
|
virtual void resetRegisters();
|
||||||
|
|
||||||
int getLatency() const override
|
int getLatency() const
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,9 +171,9 @@ int InterpolateShannon::transposeStereo(SAMPLETYPE *pdest,
|
||||||
|
|
||||||
/// Transpose stereo audio. Returns number of produced output samples, and
|
/// Transpose stereo audio. Returns number of produced output samples, and
|
||||||
/// updates "srcSamples" to amount of consumed source samples
|
/// updates "srcSamples" to amount of consumed source samples
|
||||||
int InterpolateShannon::transposeMulti(SAMPLETYPE *pdest,
|
int InterpolateShannon::transposeMulti(SAMPLETYPE *,
|
||||||
const SAMPLETYPE *psrc,
|
const SAMPLETYPE *,
|
||||||
int &srcSamples)
|
int &)
|
||||||
{
|
{
|
||||||
// not implemented
|
// not implemented
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
namespace soundtouch
|
namespace soundtouch
|
||||||
{
|
{
|
||||||
|
|
||||||
class InterpolateShannon final : public TransposerBase
|
class InterpolateShannon : public TransposerBase
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
int transposeMono(SAMPLETYPE *dest,
|
int transposeMono(SAMPLETYPE *dest,
|
||||||
|
@ -63,7 +63,7 @@ public:
|
||||||
|
|
||||||
void resetRegisters() override;
|
void resetRegisters() override;
|
||||||
|
|
||||||
int getLatency() const override
|
virtual int getLatency() const override
|
||||||
{
|
{
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,8 +131,6 @@ void RateTransposer::putSamples(const SAMPLETYPE *samples, uint nSamples)
|
||||||
// the 'set_returnBuffer_size' function.
|
// the 'set_returnBuffer_size' function.
|
||||||
void RateTransposer::processSamples(const SAMPLETYPE *src, uint nSamples)
|
void RateTransposer::processSamples(const SAMPLETYPE *src, uint nSamples)
|
||||||
{
|
{
|
||||||
uint count;
|
|
||||||
|
|
||||||
if (nSamples == 0) return;
|
if (nSamples == 0) return;
|
||||||
|
|
||||||
// Store samples to input buffer
|
// Store samples to input buffer
|
||||||
|
@ -142,7 +140,7 @@ void RateTransposer::processSamples(const SAMPLETYPE *src, uint nSamples)
|
||||||
// the filter
|
// the filter
|
||||||
if (bUseAAFilter == false)
|
if (bUseAAFilter == false)
|
||||||
{
|
{
|
||||||
count = pTransposer->transpose(outputBuffer, inputBuffer);
|
(void)pTransposer->transpose(outputBuffer, inputBuffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,7 +307,7 @@ TransposerBase *TransposerBase::newInstance()
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -413,15 +413,15 @@ int SoundTouch::getSetting(int settingId) const
|
||||||
return (uint)pTDStretch->isQuickSeekEnabled();
|
return (uint)pTDStretch->isQuickSeekEnabled();
|
||||||
|
|
||||||
case SETTING_SEQUENCE_MS:
|
case SETTING_SEQUENCE_MS:
|
||||||
pTDStretch->getParameters(NULL, &temp, NULL, NULL);
|
pTDStretch->getParameters(nullptr, &temp, nullptr, nullptr);
|
||||||
return temp;
|
return temp;
|
||||||
|
|
||||||
case SETTING_SEEKWINDOW_MS:
|
case SETTING_SEEKWINDOW_MS:
|
||||||
pTDStretch->getParameters(NULL, NULL, &temp, NULL);
|
pTDStretch->getParameters(nullptr, nullptr, &temp, nullptr);
|
||||||
return temp;
|
return temp;
|
||||||
|
|
||||||
case SETTING_OVERLAP_MS:
|
case SETTING_OVERLAP_MS:
|
||||||
pTDStretch->getParameters(NULL, NULL, NULL, &temp);
|
pTDStretch->getParameters(nullptr, nullptr, nullptr, &temp);
|
||||||
return temp;
|
return temp;
|
||||||
|
|
||||||
case SETTING_NOMINAL_INPUT_SEQUENCE :
|
case SETTING_NOMINAL_INPUT_SEQUENCE :
|
||||||
|
|
|
@ -54,25 +54,6 @@ using namespace soundtouch;
|
||||||
|
|
||||||
#define max(x, y) (((x) > (y)) ? (x) : (y))
|
#define max(x, y) (((x) > (y)) ? (x) : (y))
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Constant definitions
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
// Table for the hierarchical mixing position seeking algorithm
|
|
||||||
const short _scanOffsets[5][24]={
|
|
||||||
{ 124, 186, 248, 310, 372, 434, 496, 558, 620, 682, 744, 806,
|
|
||||||
868, 930, 992, 1054, 1116, 1178, 1240, 1302, 1364, 1426, 1488, 0},
|
|
||||||
{-100, -75, -50, -25, 25, 50, 75, 100, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
||||||
{ -20, -15, -10, -5, 5, 10, 15, 20, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
||||||
{ -4, -3, -2, -1, 1, 2, 3, 4, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
||||||
{ 121, 114, 97, 114, 98, 105, 108, 32, 104, 99, 117, 111,
|
|
||||||
116, 100, 110, 117, 111, 115, 0, 0, 0, 0, 0, 0}};
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* Implementation of the class 'TDStretch'
|
* Implementation of the class 'TDStretch'
|
||||||
|
@ -85,8 +66,8 @@ TDStretch::TDStretch() : FIFOProcessor(&outputBuffer)
|
||||||
bQuickSeek = false;
|
bQuickSeek = false;
|
||||||
channels = 2;
|
channels = 2;
|
||||||
|
|
||||||
pMidBuffer = NULL;
|
pMidBuffer = nullptr;
|
||||||
pMidBufferUnaligned = NULL;
|
pMidBufferUnaligned = nullptr;
|
||||||
overlapLength = 0;
|
overlapLength = 0;
|
||||||
|
|
||||||
bAutoSeqSetting = true;
|
bAutoSeqSetting = true;
|
||||||
|
@ -162,7 +143,7 @@ void TDStretch::setParameters(int aSampleRate, int aSequenceMS,
|
||||||
|
|
||||||
|
|
||||||
/// Get routine control parameters, see setParameters() function.
|
/// Get routine control parameters, see setParameters() function.
|
||||||
/// Any of the parameters to this function can be NULL, in such case corresponding parameter
|
/// Any of the parameters to this function can be nullptr, in such case corresponding parameter
|
||||||
/// value isn't returned.
|
/// value isn't returned.
|
||||||
void TDStretch::getParameters(int *pSampleRate, int *pSequenceMs, int *pSeekWindowMs, int *pOverlapMs) const
|
void TDStretch::getParameters(int *pSampleRate, int *pSequenceMs, int *pSeekWindowMs, int *pOverlapMs) const
|
||||||
{
|
{
|
||||||
|
@ -759,7 +740,7 @@ void TDStretch::acceptNewOverlapLength(int newOverlapLength)
|
||||||
|
|
||||||
// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
||||||
// depending on if we've a MMX/SSE/etc-capable CPU available or not.
|
// depending on if we've a MMX/SSE/etc-capable CPU available or not.
|
||||||
void * TDStretch::operator new(size_t s)
|
void * TDStretch::operator new(size_t)
|
||||||
{
|
{
|
||||||
// Notice! don't use "new TDStretch" directly, use "newInstance" to create a new instance instead!
|
// Notice! don't use "new TDStretch" directly, use "newInstance" to create a new instance instead!
|
||||||
ST_THROW_RT_ERROR("Error in TDStretch::new: Don't use 'new TDStretch' directly, use 'newInstance' member instead!");
|
ST_THROW_RT_ERROR("Error in TDStretch::new: Don't use 'new TDStretch' directly, use 'newInstance' member instead!");
|
||||||
|
@ -772,6 +753,7 @@ TDStretch * TDStretch::newInstance()
|
||||||
uint uExtensions;
|
uint uExtensions;
|
||||||
|
|
||||||
uExtensions = detectCPUextensions();
|
uExtensions = detectCPUextensions();
|
||||||
|
(void)uExtensions;
|
||||||
|
|
||||||
// Check if MMX/SSE instruction set extensions supported by CPU
|
// Check if MMX/SSE instruction set extensions supported by CPU
|
||||||
|
|
||||||
|
|
|
@ -217,7 +217,7 @@ public:
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Get routine control parameters, see setParameters() function.
|
/// Get routine control parameters, see setParameters() function.
|
||||||
/// Any of the parameters to this function can be NULL, in such case corresponding parameter
|
/// Any of the parameters to this function can be nullptr, in such case corresponding parameter
|
||||||
/// value isn't returned.
|
/// value isn't returned.
|
||||||
void getParameters(int *pSampleRate, int *pSequenceMs, int *pSeekWindowMs, int *pOverlapMs) const;
|
void getParameters(int *pSampleRate, int *pSequenceMs, int *pSeekWindowMs, int *pOverlapMs) const;
|
||||||
|
|
||||||
|
|
|
@ -294,8 +294,8 @@ void TDStretchMMX::overlapStereo(short *output, const short *input) const
|
||||||
|
|
||||||
FIRFilterMMX::FIRFilterMMX() : FIRFilter()
|
FIRFilterMMX::FIRFilterMMX() : FIRFilter()
|
||||||
{
|
{
|
||||||
filterCoeffsAlign = NULL;
|
filterCoeffsAlign = nullptr;
|
||||||
filterCoeffsUnalign = NULL;
|
filterCoeffsUnalign = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -195,16 +195,16 @@ double TDStretchSSE::calcCrossCorrAccumulate(const float *pV1, const float *pV2,
|
||||||
|
|
||||||
FIRFilterSSE::FIRFilterSSE() : FIRFilter()
|
FIRFilterSSE::FIRFilterSSE() : FIRFilter()
|
||||||
{
|
{
|
||||||
filterCoeffsAlign = NULL;
|
filterCoeffsAlign = nullptr;
|
||||||
filterCoeffsUnalign = NULL;
|
filterCoeffsUnalign = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FIRFilterSSE::~FIRFilterSSE()
|
FIRFilterSSE::~FIRFilterSSE()
|
||||||
{
|
{
|
||||||
delete[] filterCoeffsUnalign;
|
delete[] filterCoeffsUnalign;
|
||||||
filterCoeffsAlign = NULL;
|
filterCoeffsAlign = nullptr;
|
||||||
filterCoeffsUnalign = NULL;
|
filterCoeffsUnalign = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -245,10 +245,10 @@ uint FIRFilterSSE::evaluateFilterStereo(float *dest, const float *source, uint n
|
||||||
|
|
||||||
if (count < 2) return 0;
|
if (count < 2) return 0;
|
||||||
|
|
||||||
assert(source != NULL);
|
assert(source != nullptr);
|
||||||
assert(dest != NULL);
|
assert(dest != nullptr);
|
||||||
assert((length % 8) == 0);
|
assert((length % 8) == 0);
|
||||||
assert(filterCoeffsAlign != NULL);
|
assert(filterCoeffsAlign != nullptr);
|
||||||
assert(((ulongptr)filterCoeffsAlign) % 16 == 0);
|
assert(((ulongptr)filterCoeffsAlign) % 16 == 0);
|
||||||
|
|
||||||
// filter is evaluated for two stereo samples with each iteration, thus use of 'j += 2'
|
// filter is evaluated for two stereo samples with each iteration, thus use of 'j += 2'
|
||||||
|
|
Loading…
Reference in New Issue