mirror of
https://github.com/RPCS3/soundtouch.git
synced 2024-11-09 12:22:51 +01:00
Windows: SoundStretch to accept wide-character command line attributes to support asian/non-latin files names.
This commit is contained in:
parent
74514f5597
commit
375e6ccfe9
@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
project(SoundTouch VERSION 2.3.2 LANGUAGES CXX)
|
||||
project(SoundTouch VERSION 2.3.3 LANGUAGES CXX)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
<body class="normal">
|
||||
<hr>
|
||||
<h1>SoundTouch audio processing library v2.3.2</h1>
|
||||
<p class="normal">SoundTouch library Copyright © Olli Parviainen 2001-2022</p>
|
||||
<p class="normal">SoundTouch library Copyright © Olli Parviainen 2001-2024</p>
|
||||
<hr>
|
||||
<h2>1. Introduction </h2>
|
||||
<p>SoundTouch is an open-source audio processing library that allows
|
||||
@ -450,7 +450,7 @@
|
||||
<h2><a name="SoundStretch"></a>4. SoundStretch audio processing utility
|
||||
</h2>
|
||||
<p>SoundStretch audio processing utility<br>
|
||||
Copyright (c) Olli Parviainen 2002-2022</p>
|
||||
Copyright (c) Olli Parviainen 2002-2024</p>
|
||||
<p>SoundStretch is a simple command-line application that can change
|
||||
tempo, pitch and playback rates of WAV sound files. This program is
|
||||
intended primarily to demonstrate how the "SoundTouch" library can be
|
||||
@ -874,6 +874,10 @@
|
||||
<li> Initial release</li>
|
||||
</ul>
|
||||
<h3>5.2. SoundStretch application Change History </h3>
|
||||
<p><b>2.3.3:</b></p>
|
||||
<ul>
|
||||
<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>
|
||||
<ul>
|
||||
<li>Added support for WAV file 'fact' information chunk.</li>
|
||||
|
@ -72,10 +72,10 @@ namespace soundtouch
|
||||
{
|
||||
|
||||
/// Soundtouch library version string
|
||||
#define SOUNDTOUCH_VERSION "2.3.2"
|
||||
#define SOUNDTOUCH_VERSION "2.3.3"
|
||||
|
||||
/// SoundTouch library version id
|
||||
#define SOUNDTOUCH_VERSION_ID (20302)
|
||||
#define SOUNDTOUCH_VERSION_ID (20303)
|
||||
|
||||
//
|
||||
// Available setting IDs for the 'setSetting' & 'get_setting' functions:
|
||||
|
@ -30,15 +30,18 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "RunParameters.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace soundstretch
|
||||
{
|
||||
|
||||
// Program usage instructions
|
||||
|
||||
static const char licenseText[] =
|
||||
static const char licenseText[] =
|
||||
" LICENSE:\n"
|
||||
" ========\n"
|
||||
" \n"
|
||||
@ -61,12 +64,12 @@ static const char licenseText[] =
|
||||
"This application is distributed with full source codes; however, if you\n"
|
||||
"didn't receive them, please visit the author's homepage (see the link above).";
|
||||
|
||||
static const char whatText[] =
|
||||
static const char whatText[] =
|
||||
"This application processes WAV audio files by modifying the sound tempo,\n"
|
||||
"pitch and playback rate properties independently from each other.\n"
|
||||
"\n";
|
||||
|
||||
static const char usage[] =
|
||||
static const char usage[] =
|
||||
"Usage :\n"
|
||||
" soundstretch infilename outfilename [switches]\n"
|
||||
"\n"
|
||||
@ -94,9 +97,8 @@ static int _toLowerCase(int c)
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
// Constructor
|
||||
RunParameters::RunParameters(const int nParams, const char * const paramStr[])
|
||||
RunParameters::RunParameters(int nParams, const CHARTYPE* paramStr[])
|
||||
{
|
||||
int i;
|
||||
int nFirstParam;
|
||||
@ -112,28 +114,17 @@ RunParameters::RunParameters(const int nParams, const char * const paramStr[])
|
||||
}
|
||||
string msg = whatText;
|
||||
msg += usage;
|
||||
ST_THROW_RT_ERROR(msg.c_str());
|
||||
throw(msg);
|
||||
}
|
||||
|
||||
inFileName = nullptr;
|
||||
outFileName = nullptr;
|
||||
tempoDelta = 0;
|
||||
pitchDelta = 0;
|
||||
rateDelta = 0;
|
||||
quick = 0;
|
||||
noAntiAlias = 0;
|
||||
goalBPM = 0;
|
||||
speech = false;
|
||||
detectBPM = false;
|
||||
|
||||
// Get input & output file names
|
||||
inFileName = (char*)paramStr[1];
|
||||
outFileName = (char*)paramStr[2];
|
||||
inFileName = paramStr[1];
|
||||
outFileName = paramStr[2];
|
||||
|
||||
if (outFileName[0] == '-')
|
||||
{
|
||||
// no outputfile name was given but parameters
|
||||
outFileName = nullptr;
|
||||
// outputfile name was omitted but other parameter switches given instead
|
||||
outFileName = STRING_CONST("");
|
||||
nFirstParam = 2;
|
||||
}
|
||||
else
|
||||
@ -182,25 +173,33 @@ void RunParameters::checkLimits()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Unknown switch parameter -- throws an exception with an error message
|
||||
void RunParameters::throwIllegalParamExp(const string &str) const
|
||||
// Convert STRING to std::string. Actually needed only if STRING is std::wstring, but conversion penalty is negligible
|
||||
std::string convertString(const STRING& str)
|
||||
{
|
||||
string msg = "ERROR : Illegal parameter \"";
|
||||
msg += str;
|
||||
msg += "\".\n\n";
|
||||
msg += usage;
|
||||
ST_THROW_RT_ERROR(msg.c_str());
|
||||
std::string res;
|
||||
for (auto c : str)
|
||||
{
|
||||
res += (char)c;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// Unknown switch parameter -- throws an exception with an error message
|
||||
void RunParameters::throwIllegalParamExp(const STRING &str) const
|
||||
{
|
||||
string msg = "ERROR : Illegal parameter \"";
|
||||
msg += convertString(str);
|
||||
msg += "\".\n\n";
|
||||
msg += usage;
|
||||
ST_THROW_RT_ERROR(msg);
|
||||
}
|
||||
|
||||
void RunParameters::throwLicense() const
|
||||
{
|
||||
ST_THROW_RT_ERROR(licenseText);
|
||||
}
|
||||
|
||||
|
||||
float RunParameters::parseSwitchValue(const string &str) const
|
||||
float RunParameters::parseSwitchValue(const STRING& str) const
|
||||
{
|
||||
int pos;
|
||||
|
||||
@ -212,14 +211,14 @@ float RunParameters::parseSwitchValue(const string &str) const
|
||||
}
|
||||
|
||||
// Read numerical parameter value after '='
|
||||
return (float)atof(str.substr(pos + 1).c_str());
|
||||
return (float)stof(str.substr(pos + 1).c_str());
|
||||
}
|
||||
|
||||
|
||||
// Interprets a single switch parameter string of format "-switch=xx"
|
||||
// Valid switches are "-tempo=xx", "-pitch=xx" and "-rate=xx". Stores
|
||||
// switch values into 'params' structure.
|
||||
void RunParameters::parseSwitchParam(const string &str)
|
||||
void RunParameters::parseSwitchParam(const STRING& str)
|
||||
{
|
||||
int upS;
|
||||
|
||||
@ -289,3 +288,5 @@ void RunParameters::parseSwitchParam(const string &str)
|
||||
throwIllegalParamExp(str);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -32,34 +32,39 @@
|
||||
#ifndef RUNPARAMETERS_H
|
||||
#define RUNPARAMETERS_H
|
||||
|
||||
#include "STTypes.h"
|
||||
#include <string>
|
||||
#include "STTypes.h"
|
||||
#include "SS_CharTypes.h"
|
||||
#include "WavFile.h"
|
||||
|
||||
using namespace std;
|
||||
namespace soundstretch
|
||||
{
|
||||
|
||||
/// Parses command line parameters into program parameters
|
||||
class RunParameters
|
||||
{
|
||||
private:
|
||||
void throwIllegalParamExp(const string &str) const;
|
||||
void throwIllegalParamExp(const STRING& str) const;
|
||||
void throwLicense() const;
|
||||
void parseSwitchParam(const string &str);
|
||||
void parseSwitchParam(const STRING& str);
|
||||
void checkLimits();
|
||||
float parseSwitchValue(const string &str) const;
|
||||
float parseSwitchValue(const STRING& tr) const;
|
||||
|
||||
public:
|
||||
char *inFileName;
|
||||
char *outFileName;
|
||||
float tempoDelta;
|
||||
float pitchDelta;
|
||||
float rateDelta;
|
||||
int quick;
|
||||
int noAntiAlias;
|
||||
float goalBPM;
|
||||
bool detectBPM;
|
||||
bool speech;
|
||||
STRING inFileName;
|
||||
STRING outFileName;
|
||||
float tempoDelta{ 0 };
|
||||
float pitchDelta{ 0 };
|
||||
float rateDelta{ 0 };
|
||||
int quick{ 0 };
|
||||
int noAntiAlias{ 0 };
|
||||
float goalBPM{ 0 };
|
||||
bool detectBPM{ false };
|
||||
bool speech{ false };
|
||||
|
||||
RunParameters(const int nParams, const char * const paramStr[]);
|
||||
RunParameters(int nParams, const CHARTYPE* paramStr[]);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -42,17 +42,26 @@
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <cassert>
|
||||
#include <climits>
|
||||
|
||||
#include "WavFile.h"
|
||||
#include "STTypes.h"
|
||||
|
||||
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 waveStr[] = "WAVE";
|
||||
static const char fmtStr[] = "fmt ";
|
||||
static const char fmtStr[] = "fmt ";
|
||||
static const char factStr[] = "fact";
|
||||
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.
|
||||
|
||||
#ifdef BYTE_ORDER
|
||||
// In gcc compiler detect the byte order automatically
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
// big-endian platform.
|
||||
#define _BIG_ENDIAN_
|
||||
#endif
|
||||
// In gcc compiler detect the byte order automatically
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
// big-endian platform.
|
||||
#define _BIG_ENDIAN_
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#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
|
||||
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 32bit integer
|
||||
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)
|
||||
// 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++)
|
||||
{
|
||||
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]);
|
||||
}
|
||||
pData[i] = _swap16(pData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#else // BIG_ENDIAN
|
||||
// little-endian CPU, WAV file is ok as such
|
||||
// little-endian CPU, WAV file is ok as such
|
||||
|
||||
// dummy helper-function
|
||||
static inline int _swap32(int &dwData)
|
||||
{
|
||||
// do nothing
|
||||
return dwData;
|
||||
}
|
||||
// dummy helper-function
|
||||
static inline int _swap32(int& dwData)
|
||||
{
|
||||
// do nothing
|
||||
return dwData;
|
||||
}
|
||||
|
||||
// dummy helper-function
|
||||
static inline short _swap16(short &wData)
|
||||
{
|
||||
// do nothing
|
||||
return wData;
|
||||
}
|
||||
// dummy helper-function
|
||||
static inline short _swap16(short& wData)
|
||||
{
|
||||
// do nothing
|
||||
return wData;
|
||||
}
|
||||
|
||||
// dummy helper-function
|
||||
static inline void _swap16Buffer(short *, int)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
// dummy helper-function
|
||||
static inline void _swap16Buffer(short*, int)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
#endif // BIG_ENDIAN
|
||||
|
||||
@ -151,7 +160,7 @@ WavFileBase::~WavFileBase()
|
||||
|
||||
|
||||
/// Get pointer to conversion buffer of at min. given size
|
||||
void *WavFileBase::getConvBuffer(int sizeBytes)
|
||||
void* WavFileBase::getConvBuffer(int sizeBytes)
|
||||
{
|
||||
if (convBuffSize < sizeBytes)
|
||||
{
|
||||
@ -169,32 +178,26 @@ void *WavFileBase::getConvBuffer(int sizeBytes)
|
||||
// Class WavInFile
|
||||
//
|
||||
|
||||
WavInFile::WavInFile(const char *fileName)
|
||||
WavInFile::WavInFile(const STRING& fileName)
|
||||
{
|
||||
// Try to open the file for reading
|
||||
fptr = fopen(fileName, "rb");
|
||||
if (fptr == nullptr)
|
||||
fptr = FOPEN(fileName.c_str(), "rb");
|
||||
if (fptr == nullptr)
|
||||
{
|
||||
// didn't succeed
|
||||
string msg = "Error : Unable to open file \"";
|
||||
msg += fileName;
|
||||
msg += "\" for reading.";
|
||||
ST_THROW_RT_ERROR(msg.c_str());
|
||||
ST_THROW_RT_ERROR("Error : Unable to open file for reading.");
|
||||
}
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
WavInFile::WavInFile(FILE *file)
|
||||
WavInFile::WavInFile(FILE* file)
|
||||
{
|
||||
// Try to open the file for reading
|
||||
fptr = file;
|
||||
if (!file)
|
||||
if (!file)
|
||||
{
|
||||
// didn't succeed
|
||||
string msg = "Error : Unable to access input stream for reading";
|
||||
ST_THROW_RT_ERROR(msg.c_str());
|
||||
ST_THROW_RT_ERROR("Error : Unable to access input stream for reading");
|
||||
}
|
||||
|
||||
init();
|
||||
@ -211,19 +214,17 @@ void WavInFile::init()
|
||||
|
||||
// Read the file headers
|
||||
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");
|
||||
}
|
||||
|
||||
// sanity check for format parameters
|
||||
if ((header.format.channel_number < 1) || (header.format.channel_number > 9) ||
|
||||
(header.format.sample_rate < 4000) || (header.format.sample_rate > 192000) ||
|
||||
if ((header.format.channel_number < 1) || (header.format.channel_number > 9) ||
|
||||
(header.format.sample_rate < 4000) || (header.format.sample_rate > 192000) ||
|
||||
(header.format.byte_per_sample < 1) || (header.format.byte_per_sample > 320) ||
|
||||
(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.");
|
||||
}
|
||||
|
||||
@ -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;
|
||||
uint afterDataRead;
|
||||
@ -274,7 +275,7 @@ int WavInFile::read(unsigned char *buffer, int maxElems)
|
||||
|
||||
numBytes = maxElems;
|
||||
afterDataRead = dataRead + numBytes;
|
||||
if (afterDataRead > header.data.data_len)
|
||||
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;
|
||||
@ -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;
|
||||
int numBytes;
|
||||
@ -298,53 +299,53 @@ int WavInFile::read(short *buffer, int maxElems)
|
||||
assert(buffer);
|
||||
switch (header.format.bits_per_sample)
|
||||
{
|
||||
case 8:
|
||||
{
|
||||
// 8 bit format
|
||||
unsigned char *temp = (unsigned char*)getConvBuffer(maxElems);
|
||||
int i;
|
||||
case 8:
|
||||
{
|
||||
// 8 bit format
|
||||
unsigned char* temp = (unsigned char*)getConvBuffer(maxElems);
|
||||
int i;
|
||||
|
||||
numElems = read(temp, maxElems);
|
||||
// convert from 8 to 16 bit
|
||||
for (i = 0; i < numElems; i ++)
|
||||
{
|
||||
buffer[i] = (short)(((short)temp[i] - 128) * 256);
|
||||
}
|
||||
break;
|
||||
numElems = read(temp, maxElems);
|
||||
// convert from 8 to 16 bit
|
||||
for (i = 0; i < numElems; i++)
|
||||
{
|
||||
buffer[i] = (short)(((short)temp[i] - 128) * 256);
|
||||
}
|
||||
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:
|
||||
{
|
||||
// 16 bit format
|
||||
numBytes = (int)fread(buffer, 1, numBytes, fptr);
|
||||
dataRead += numBytes;
|
||||
numElems = numBytes / 2;
|
||||
|
||||
assert(sizeof(short) == 2);
|
||||
// 16bit samples, swap byte order if necessary
|
||||
_swap16Buffer((short*)buffer, numElems);
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
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;
|
||||
@ -353,7 +354,7 @@ int WavInFile::read(short *buffer, int maxElems)
|
||||
|
||||
/// Read data in float format. Notice that when reading in float format
|
||||
/// 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;
|
||||
int numBytes;
|
||||
@ -374,7 +375,7 @@ int WavInFile::read(float *buffer, int maxElems)
|
||||
|
||||
numBytes = maxElems * bytesPerSample;
|
||||
afterDataRead = dataRead + numBytes;
|
||||
if (afterDataRead > header.data.data_len)
|
||||
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;
|
||||
@ -382,7 +383,7 @@ int WavInFile::read(float *buffer, int maxElems)
|
||||
}
|
||||
|
||||
// read raw data into temporary buffer
|
||||
char *temp = (char*)getConvBuffer(numBytes);
|
||||
char* temp = (char*)getConvBuffer(numBytes);
|
||||
numBytes = (int)fread(temp, 1, numBytes, fptr);
|
||||
dataRead += numBytes;
|
||||
|
||||
@ -391,56 +392,56 @@ int WavInFile::read(float *buffer, int maxElems)
|
||||
// swap byte ordert & convert to float, depending on sample format
|
||||
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;
|
||||
double conv = 1.0 / 128.0;
|
||||
for (int i = 0; i < numElems; i ++)
|
||||
{
|
||||
buffer[i] = (float)(temp2[i] * conv - 1.0);
|
||||
}
|
||||
break;
|
||||
buffer[i] = (float)(temp2[i] * conv - 1.0);
|
||||
}
|
||||
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;
|
||||
double conv = 1.0 / 32768.0;
|
||||
for (int i = 0; i < numElems; i ++)
|
||||
{
|
||||
short value = temp2[i];
|
||||
buffer[i] = (float)(_swap16(value) * conv);
|
||||
}
|
||||
break;
|
||||
short value = temp2[i];
|
||||
buffer[i] = (float)(_swap16(value) * conv);
|
||||
}
|
||||
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;
|
||||
double conv = 1.0 / 8388608.0;
|
||||
for (int i = 0; i < numElems; i ++)
|
||||
{
|
||||
int value = *((int*)temp2);
|
||||
value = _swap32(value) & 0x00ffffff; // take 24 bits
|
||||
value |= (value & 0x00800000) ? 0xff000000 : 0; // extend minus sign bits
|
||||
buffer[i] = (float)(value * conv);
|
||||
temp2 += 3;
|
||||
}
|
||||
break;
|
||||
int value = *((int*)temp2);
|
||||
value = _swap32(value) & 0x00ffffff; // take 24 bits
|
||||
value |= (value & 0x00800000) ? 0xff000000 : 0; // extend minus sign bits
|
||||
buffer[i] = (float)(value * conv);
|
||||
temp2 += 3;
|
||||
}
|
||||
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;
|
||||
double conv = 1.0 / 2147483648.0;
|
||||
assert(sizeof(int) == 4);
|
||||
for (int i = 0; i < numElems; i ++)
|
||||
{
|
||||
int value = temp2[i];
|
||||
buffer[i] = (float)(_swap32(value) * conv);
|
||||
}
|
||||
break;
|
||||
int value = temp2[i];
|
||||
buffer[i] = (float)(_swap32(value) * conv);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return numElems;
|
||||
@ -462,15 +463,15 @@ static int isAlpha(char c)
|
||||
|
||||
|
||||
// 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;
|
||||
|
||||
c = str[0];
|
||||
while (c)
|
||||
while (c)
|
||||
{
|
||||
if (isAlpha(c) == 0) return 0;
|
||||
str ++;
|
||||
str++;
|
||||
c = str[0];
|
||||
}
|
||||
|
||||
@ -483,7 +484,7 @@ int WavInFile::readRIFFBlock()
|
||||
if (fread(&(header.riff), sizeof(WavRiff), 1, fptr) != 1) return -1;
|
||||
|
||||
// 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');
|
||||
if (memcmp(riffStr, header.riff.riff_char, 4) != 0) return -1;
|
||||
@ -500,7 +501,7 @@ int WavInFile::readHeaderBlock()
|
||||
string sLabel;
|
||||
|
||||
// lead label string
|
||||
if (fread(label, 1, 4, fptr) !=4) return -1;
|
||||
if (fread(label, 1, 4, fptr) != 4) return -1;
|
||||
label[4] = 0;
|
||||
|
||||
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;
|
||||
|
||||
// swap byte order if necessary
|
||||
_swap16((short &)header.format.fixed); // short int fixed;
|
||||
_swap16((short &)header.format.channel_number); // short int channel_number;
|
||||
_swap32((int &)header.format.sample_rate); // int sample_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.bits_per_sample); // short int bits_per_sample;
|
||||
_swap16((short&)header.format.fixed); // short int fixed;
|
||||
_swap16((short&)header.format.channel_number); // short int channel_number;
|
||||
_swap32((int&)header.format.sample_rate); // int sample_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.bits_per_sample); // short int bits_per_sample;
|
||||
|
||||
// if format_len is larger than expected, skip the extra data
|
||||
if (nDump > 0)
|
||||
@ -581,7 +582,7 @@ int WavInFile::readHeaderBlock()
|
||||
if (fread(&(header.fact.fact_sample_len), nLen, 1, fptr) != 1) return -1;
|
||||
|
||||
// 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 (nDump > 0)
|
||||
@ -598,7 +599,7 @@ int WavInFile::readHeaderBlock()
|
||||
if (fread(&(header.data.data_len), sizeof(uint), 1, fptr) != 1) return -1;
|
||||
|
||||
// swap byte order if necessary
|
||||
_swap32((int &)header.data.data_len);
|
||||
_swap32((int&)header.data.data_len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -611,7 +612,7 @@ int WavInFile::readHeaderBlock()
|
||||
// read length
|
||||
if (fread(&len, sizeof(len), 1, fptr) != 1) return -1;
|
||||
// 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 (feof(fptr)) return -1; // unexpected eof
|
||||
@ -703,17 +704,13 @@ uint WavInFile::getElapsedMS() const
|
||||
// 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;
|
||||
fptr = fopen(fileName, "wb");
|
||||
if (fptr == nullptr)
|
||||
fptr = FOPEN(fileName.c_str(), "wb");
|
||||
if (fptr == nullptr)
|
||||
{
|
||||
string msg = "Error : Unable to open file \"";
|
||||
msg += fileName;
|
||||
msg += "\" for writing.";
|
||||
//pmsg = msg.c_str;
|
||||
ST_THROW_RT_ERROR(msg.c_str());
|
||||
ST_THROW_RT_ERROR("Error : Unable to open file for writing.");
|
||||
}
|
||||
|
||||
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;
|
||||
fptr = file;
|
||||
if (fptr == nullptr)
|
||||
if (fptr == nullptr)
|
||||
{
|
||||
string msg = "Error : Unable to access output file stream.";
|
||||
ST_THROW_RT_ERROR(msg.c_str());
|
||||
ST_THROW_RT_ERROR("Error : Unable to access output file stream.");
|
||||
}
|
||||
|
||||
fillInHeader(sampleRate, bits, channels);
|
||||
@ -788,8 +784,8 @@ void WavOutFile::finishHeader()
|
||||
// supplement the file length into the header structure
|
||||
header.riff.package_len = bytesWritten + sizeof(WavHeader) - sizeof(WavRiff) + 4;
|
||||
header.data.data_len = bytesWritten;
|
||||
header.fact.fact_sample_len = bytesWritten / header.format.byte_per_sample;
|
||||
|
||||
header.fact.fact_sample_len = bytesWritten / header.format.byte_per_sample;
|
||||
|
||||
writeHeader();
|
||||
}
|
||||
|
||||
@ -801,18 +797,18 @@ void WavOutFile::writeHeader()
|
||||
|
||||
// swap byte order if necessary
|
||||
hdrTemp = header;
|
||||
_swap32((int &)hdrTemp.riff.package_len);
|
||||
_swap32((int &)hdrTemp.format.format_len);
|
||||
_swap16((short &)hdrTemp.format.fixed);
|
||||
_swap16((short &)hdrTemp.format.channel_number);
|
||||
_swap32((int &)hdrTemp.format.sample_rate);
|
||||
_swap32((int &)hdrTemp.format.byte_rate);
|
||||
_swap16((short &)hdrTemp.format.byte_per_sample);
|
||||
_swap16((short &)hdrTemp.format.bits_per_sample);
|
||||
_swap32((int &)hdrTemp.data.data_len);
|
||||
_swap32((int &)hdrTemp.fact.fact_len);
|
||||
_swap32((int &)hdrTemp.fact.fact_sample_len);
|
||||
|
||||
_swap32((int&)hdrTemp.riff.package_len);
|
||||
_swap32((int&)hdrTemp.format.format_len);
|
||||
_swap16((short&)hdrTemp.format.fixed);
|
||||
_swap16((short&)hdrTemp.format.channel_number);
|
||||
_swap32((int&)hdrTemp.format.sample_rate);
|
||||
_swap32((int&)hdrTemp.format.byte_rate);
|
||||
_swap16((short&)hdrTemp.format.byte_per_sample);
|
||||
_swap16((short&)hdrTemp.format.bits_per_sample);
|
||||
_swap32((int&)hdrTemp.data.data_len);
|
||||
_swap32((int&)hdrTemp.fact.fact_len);
|
||||
_swap32((int&)hdrTemp.fact.fact_sample_len);
|
||||
|
||||
// write the supplemented header in the beginning of the file
|
||||
fseek(fptr, 0, SEEK_SET);
|
||||
res = (int)fwrite(&hdrTemp, sizeof(hdrTemp), 1, fptr);
|
||||
@ -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;
|
||||
|
||||
@ -837,7 +833,7 @@ void WavOutFile::write(const unsigned char *buffer, int numElems)
|
||||
assert(sizeof(char) == 1);
|
||||
|
||||
res = (int)fwrite(buffer, 1, numElems, fptr);
|
||||
if (res != numElems)
|
||||
if (res != numElems)
|
||||
{
|
||||
ST_THROW_RT_ERROR("Error while writing to a wav file.");
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -855,47 +851,47 @@ void WavOutFile::write(const short *buffer, int numElems)
|
||||
|
||||
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;
|
||||
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;
|
||||
temp[i] = (unsigned char)(buffer[i] / 256 + 128);
|
||||
}
|
||||
// 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
|
||||
|
||||
// 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;
|
||||
ST_THROW_RT_ERROR("Error while writing to a wav file.");
|
||||
}
|
||||
bytesWritten += 2 * 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());
|
||||
}
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -903,10 +899,10 @@ void WavOutFile::write(const short *buffer, int numElems)
|
||||
/// Convert from float to integer and saturate
|
||||
inline int saturate(float fvalue, float minval, float maxval)
|
||||
{
|
||||
if (fvalue > maxval)
|
||||
if (fvalue > maxval)
|
||||
{
|
||||
fvalue = maxval;
|
||||
}
|
||||
}
|
||||
else if (fvalue < minval)
|
||||
{
|
||||
fvalue = minval;
|
||||
@ -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 bytesPerSample;
|
||||
@ -924,63 +920,65 @@ void WavOutFile::write(const float *buffer, int numElems)
|
||||
|
||||
bytesPerSample = header.format.bits_per_sample / 8;
|
||||
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)
|
||||
{
|
||||
case 1:
|
||||
case 1:
|
||||
{
|
||||
unsigned char* temp2 = (unsigned char*)temp;
|
||||
for (int i = 0; i < numElems; i++)
|
||||
{
|
||||
unsigned char *temp2 = (unsigned char *)temp;
|
||||
for (int i = 0; i < numElems; i ++)
|
||||
{
|
||||
temp2[i] = (unsigned char)saturate(buffer[i] * 128.0f + 128.0f, 0.0f, 255.0f);
|
||||
}
|
||||
break;
|
||||
temp2[i] = (unsigned char)saturate(buffer[i] * 128.0f + 128.0f, 0.0f, 255.0f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
case 2:
|
||||
{
|
||||
short* temp2 = (short*)temp;
|
||||
for (int i = 0; i < numElems; i++)
|
||||
{
|
||||
short *temp2 = (short *)temp;
|
||||
for (int i = 0; i < numElems; i ++)
|
||||
{
|
||||
short value = (short)saturate(buffer[i] * 32768.0f, -32768.0f, 32767.0f);
|
||||
temp2[i] = _swap16(value);
|
||||
}
|
||||
break;
|
||||
short value = (short)saturate(buffer[i] * 32768.0f, -32768.0f, 32767.0f);
|
||||
temp2[i] = _swap16(value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 3:
|
||||
case 3:
|
||||
{
|
||||
char* temp2 = (char*)temp;
|
||||
for (int i = 0; i < numElems; i++)
|
||||
{
|
||||
char *temp2 = (char *)temp;
|
||||
for (int i = 0; i < numElems; i ++)
|
||||
{
|
||||
int value = saturate(buffer[i] * 8388608.0f, -8388608.0f, 8388607.0f);
|
||||
*((int*)temp2) = _swap32(value);
|
||||
temp2 += 3;
|
||||
}
|
||||
break;
|
||||
int value = saturate(buffer[i] * 8388608.0f, -8388608.0f, 8388607.0f);
|
||||
*((int*)temp2) = _swap32(value);
|
||||
temp2 += 3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
case 4:
|
||||
{
|
||||
int* temp2 = (int*)temp;
|
||||
for (int i = 0; i < numElems; i++)
|
||||
{
|
||||
int *temp2 = (int *)temp;
|
||||
for (int i = 0; i < numElems; i ++)
|
||||
{
|
||||
int value = saturate(buffer[i] * 2147483648.0f, -2147483648.0f, 2147483647.0f);
|
||||
temp2[i] = _swap32(value);
|
||||
}
|
||||
break;
|
||||
int value = saturate(buffer[i] * 2147483648.0f, -2147483648.0f, 2147483647.0f);
|
||||
temp2[i] = _swap32(value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
|
||||
int res = (int)fwrite(temp, 1, numBytes, fptr);
|
||||
|
||||
if (res != numBytes)
|
||||
if (res != numBytes)
|
||||
{
|
||||
ST_THROW_RT_ERROR("Error while writing to a wav file.");
|
||||
}
|
||||
bytesWritten += numBytes;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -40,7 +40,12 @@
|
||||
#ifndef WAVFILE_H
|
||||
#define WAVFILE_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include "SS_CharTypes.h"
|
||||
|
||||
namespace soundstretch
|
||||
{
|
||||
|
||||
#ifndef uint
|
||||
typedef unsigned int uint;
|
||||
@ -145,7 +150,7 @@ private:
|
||||
public:
|
||||
/// Constructor: Opens the given WAV file. If the file can't be opened,
|
||||
/// throws 'runtime_error' exception.
|
||||
WavInFile(const char *filename);
|
||||
WavInFile(const STRING& filename);
|
||||
|
||||
WavInFile(FILE *file);
|
||||
|
||||
@ -241,7 +246,7 @@ private:
|
||||
public:
|
||||
/// Constructor: Creates a new WAV file. Throws a 'runtime_error' exception
|
||||
/// if file creation fails.
|
||||
WavOutFile(const char *fileName, ///< Filename
|
||||
WavOutFile(const STRING& fileName, ///< Filename
|
||||
int sampleRate, ///< Sample rate (e.g. 44100 etc)
|
||||
int bits, ///< Bits per sample (8 or 16 bits)
|
||||
int channels ///< Number of channels (1=mono, 2=stereo)
|
||||
@ -271,4 +276,6 @@ public:
|
||||
);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -29,10 +29,12 @@
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include "RunParameters.h"
|
||||
#include "WavFile.h"
|
||||
#include "SoundTouch.h"
|
||||
@ -41,22 +43,25 @@
|
||||
using namespace soundtouch;
|
||||
using namespace std;
|
||||
|
||||
namespace soundstretch
|
||||
{
|
||||
|
||||
// Processing chunk size (size chosen to be divisible by 2, 4, 6, 8, 10, 12, 14, 16 channels ...)
|
||||
#define BUFF_SIZE 6720
|
||||
|
||||
#if _WIN32
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
// Macro for Win32 standard input/output stream support: Sets a file stream into binary mode
|
||||
#define SET_STREAM_TO_BIN_MODE(f) (_setmode(_fileno(f), _O_BINARY))
|
||||
// Macro for Win32 standard input/output stream support: Sets a file stream into binary mode
|
||||
#define SET_STREAM_TO_BIN_MODE(f) (_setmode(_fileno(f), _O_BINARY))
|
||||
#else
|
||||
// Not needed for GNU environment...
|
||||
#define SET_STREAM_TO_BIN_MODE(f) {}
|
||||
#define SET_STREAM_TO_BIN_MODE(f) {}
|
||||
#endif
|
||||
|
||||
|
||||
static const char _helloText[] =
|
||||
static const char _helloText[] =
|
||||
"\n"
|
||||
" SoundStretch v%s - Copyright (c) Olli Parviainen\n"
|
||||
"=========================================================\n"
|
||||
@ -68,90 +73,81 @@ static const char _helloText[] =
|
||||
"more information.\n"
|
||||
"\n";
|
||||
|
||||
static void openFiles(WavInFile **inFile, WavOutFile **outFile, const RunParameters *params)
|
||||
static void openFiles(unique_ptr<WavInFile>& inFile, unique_ptr<WavOutFile>& outFile, const RunParameters& params)
|
||||
{
|
||||
int bits, samplerate, channels;
|
||||
|
||||
if (strcmp(params->inFileName, "stdin") == 0)
|
||||
if (params.inFileName == STRING_CONST("stdin"))
|
||||
{
|
||||
// used 'stdin' as input file
|
||||
SET_STREAM_TO_BIN_MODE(stdin);
|
||||
*inFile = new WavInFile(stdin);
|
||||
inFile = make_unique<WavInFile>(stdin);
|
||||
}
|
||||
else
|
||||
{
|
||||
// open input file...
|
||||
*inFile = new WavInFile(params->inFileName);
|
||||
inFile = make_unique<WavInFile>(params.inFileName.c_str());
|
||||
}
|
||||
|
||||
// ... open output file with same sound parameters
|
||||
bits = (int)(*inFile)->getNumBits();
|
||||
samplerate = (int)(*inFile)->getSampleRate();
|
||||
channels = (int)(*inFile)->getNumChannels();
|
||||
const int bits = (int)inFile->getNumBits();
|
||||
const int samplerate = (int)inFile->getSampleRate();
|
||||
const int channels = (int)inFile->getNumChannels();
|
||||
|
||||
if (params->outFileName)
|
||||
if (!params.outFileName.empty())
|
||||
{
|
||||
if (strcmp(params->outFileName, "stdout") == 0)
|
||||
if (params.outFileName == STRING_CONST("stdout"))
|
||||
{
|
||||
SET_STREAM_TO_BIN_MODE(stdout);
|
||||
*outFile = new WavOutFile(stdout, samplerate, bits, channels);
|
||||
outFile = make_unique<WavOutFile>(stdout, samplerate, bits, channels);
|
||||
}
|
||||
else
|
||||
{
|
||||
*outFile = new WavOutFile(params->outFileName, samplerate, bits, channels);
|
||||
outFile = make_unique<WavOutFile>(params.outFileName.c_str(), samplerate, bits, channels);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*outFile = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Sets the 'SoundTouch' object up according to input file sound format &
|
||||
// command line parameters
|
||||
static void setup(SoundTouch *pSoundTouch, const WavInFile *inFile, const RunParameters *params)
|
||||
static void setup(SoundTouch& soundTouch, const WavInFile& inFile, const RunParameters& params)
|
||||
{
|
||||
int sampleRate;
|
||||
int channels;
|
||||
const int sampleRate = (int)inFile.getSampleRate();
|
||||
const int channels = (int)inFile.getNumChannels();
|
||||
soundTouch.setSampleRate(sampleRate);
|
||||
soundTouch.setChannels(channels);
|
||||
|
||||
sampleRate = (int)inFile->getSampleRate();
|
||||
channels = (int)inFile->getNumChannels();
|
||||
pSoundTouch->setSampleRate(sampleRate);
|
||||
pSoundTouch->setChannels(channels);
|
||||
soundTouch.setTempoChange(params.tempoDelta);
|
||||
soundTouch.setPitchSemiTones(params.pitchDelta);
|
||||
soundTouch.setRateChange(params.rateDelta);
|
||||
|
||||
pSoundTouch->setTempoChange(params->tempoDelta);
|
||||
pSoundTouch->setPitchSemiTones(params->pitchDelta);
|
||||
pSoundTouch->setRateChange(params->rateDelta);
|
||||
soundTouch.setSetting(SETTING_USE_QUICKSEEK, params.quick);
|
||||
soundTouch.setSetting(SETTING_USE_AA_FILTER, !(params.noAntiAlias));
|
||||
|
||||
pSoundTouch->setSetting(SETTING_USE_QUICKSEEK, params->quick);
|
||||
pSoundTouch->setSetting(SETTING_USE_AA_FILTER, !(params->noAntiAlias));
|
||||
|
||||
if (params->speech)
|
||||
if (params.speech)
|
||||
{
|
||||
// use settings for speech processing
|
||||
pSoundTouch->setSetting(SETTING_SEQUENCE_MS, 40);
|
||||
pSoundTouch->setSetting(SETTING_SEEKWINDOW_MS, 15);
|
||||
pSoundTouch->setSetting(SETTING_OVERLAP_MS, 8);
|
||||
soundTouch.setSetting(SETTING_SEQUENCE_MS, 40);
|
||||
soundTouch.setSetting(SETTING_SEEKWINDOW_MS, 15);
|
||||
soundTouch.setSetting(SETTING_OVERLAP_MS, 8);
|
||||
fprintf(stderr, "Tune processing parameters for speech processing.\n");
|
||||
}
|
||||
|
||||
// print processing information
|
||||
if (params->outFileName)
|
||||
if (!params.outFileName.empty())
|
||||
{
|
||||
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
|
||||
fprintf(stderr, "Uses 16bit integer sample type in processing.\n\n");
|
||||
#else
|
||||
#ifndef SOUNDTOUCH_FLOAT_SAMPLES
|
||||
#error "Sampletype not defined"
|
||||
#endif
|
||||
#ifndef SOUNDTOUCH_FLOAT_SAMPLES
|
||||
#error "Sampletype not defined"
|
||||
#endif
|
||||
fprintf(stderr, "Uses 32bit floating point sample type in processing.\n\n");
|
||||
#endif
|
||||
// print processing information only if outFileName given i.e. some processing will happen
|
||||
fprintf(stderr, "Processing the file with the following changes:\n");
|
||||
fprintf(stderr, " tempo change = %+g %%\n", params->tempoDelta);
|
||||
fprintf(stderr, " pitch change = %+g semitones\n", params->pitchDelta);
|
||||
fprintf(stderr, " rate change = %+g %%\n\n", params->rateDelta);
|
||||
fprintf(stderr, " tempo change = %+g %%\n", params.tempoDelta);
|
||||
fprintf(stderr, " pitch change = %+g semitones\n", params.pitchDelta);
|
||||
fprintf(stderr, " rate change = %+g %%\n\n", params.rateDelta);
|
||||
fprintf(stderr, "Working...");
|
||||
}
|
||||
else
|
||||
@ -165,30 +161,24 @@ static void setup(SoundTouch *pSoundTouch, const WavInFile *inFile, const RunPar
|
||||
|
||||
|
||||
// Processes the sound
|
||||
static void process(SoundTouch *pSoundTouch, WavInFile *inFile, WavOutFile *outFile)
|
||||
static void process(SoundTouch& soundTouch, WavInFile& inFile, WavOutFile& outFile)
|
||||
{
|
||||
int nSamples;
|
||||
int nChannels;
|
||||
int buffSizeSamples;
|
||||
SAMPLETYPE sampleBuffer[BUFF_SIZE];
|
||||
int nSamples;
|
||||
|
||||
if ((inFile == nullptr) || (outFile == nullptr)) return; // nothing to do.
|
||||
|
||||
nChannels = (int)inFile->getNumChannels();
|
||||
const int nChannels = (int)inFile.getNumChannels();
|
||||
assert(nChannels > 0);
|
||||
buffSizeSamples = BUFF_SIZE / nChannels;
|
||||
const int buffSizeSamples = BUFF_SIZE / nChannels;
|
||||
|
||||
// Process samples read from the input file
|
||||
while (inFile->eof() == 0)
|
||||
while (inFile.eof() == 0)
|
||||
{
|
||||
int num;
|
||||
|
||||
// Read a chunk of samples from the input file
|
||||
num = inFile->read(sampleBuffer, BUFF_SIZE);
|
||||
nSamples = num / (int)inFile->getNumChannels();
|
||||
const int num = inFile.read(sampleBuffer, BUFF_SIZE);
|
||||
int nSamples = num / (int)inFile.getNumChannels();
|
||||
|
||||
// Feed the samples into SoundTouch processor
|
||||
pSoundTouch->putSamples(sampleBuffer, nSamples);
|
||||
soundTouch.putSamples(sampleBuffer, nSamples);
|
||||
|
||||
// Read ready samples from SoundTouch processor & write them output file.
|
||||
// NOTES:
|
||||
@ -198,59 +188,55 @@ static void process(SoundTouch *pSoundTouch, WavInFile *inFile, WavOutFile *outF
|
||||
// ready samples than would fit into 'sampleBuffer', and for this reason
|
||||
// the 'receiveSamples' call is iterated for as many times as it
|
||||
// outputs samples.
|
||||
do
|
||||
do
|
||||
{
|
||||
nSamples = pSoundTouch->receiveSamples(sampleBuffer, buffSizeSamples);
|
||||
outFile->write(sampleBuffer, nSamples * nChannels);
|
||||
nSamples = soundTouch.receiveSamples(sampleBuffer, buffSizeSamples);
|
||||
outFile.write(sampleBuffer, nSamples * nChannels);
|
||||
} while (nSamples != 0);
|
||||
}
|
||||
|
||||
// Now the input file is processed, yet 'flush' few last samples that are
|
||||
// hiding in the SoundTouch's internal processing pipeline.
|
||||
pSoundTouch->flush();
|
||||
do
|
||||
soundTouch.flush();
|
||||
do
|
||||
{
|
||||
nSamples = pSoundTouch->receiveSamples(sampleBuffer, buffSizeSamples);
|
||||
outFile->write(sampleBuffer, nSamples * nChannels);
|
||||
nSamples = soundTouch.receiveSamples(sampleBuffer, buffSizeSamples);
|
||||
outFile.write(sampleBuffer, nSamples * nChannels);
|
||||
} while (nSamples != 0);
|
||||
}
|
||||
|
||||
|
||||
// Detect BPM rate of inFile and adjust tempo setting accordingly if necessary
|
||||
static void detectBPM(WavInFile *inFile, RunParameters *params)
|
||||
static void detectBPM(WavInFile& inFile, RunParameters& params)
|
||||
{
|
||||
float bpmValue;
|
||||
int nChannels;
|
||||
BPMDetect bpm(inFile->getNumChannels(), inFile->getSampleRate());
|
||||
BPMDetect bpm(inFile.getNumChannels(), inFile.getSampleRate());
|
||||
SAMPLETYPE sampleBuffer[BUFF_SIZE];
|
||||
|
||||
// detect bpm rate
|
||||
fprintf(stderr, "Detecting BPM rate...");
|
||||
fflush(stderr);
|
||||
|
||||
nChannels = (int)inFile->getNumChannels();
|
||||
const int nChannels = (int)inFile.getNumChannels();
|
||||
int readSize = BUFF_SIZE - BUFF_SIZE % nChannels; // round read size down to multiple of num.channels
|
||||
|
||||
// Process the 'inFile' in small blocks, repeat until whole file has
|
||||
// been processed
|
||||
while (inFile->eof() == 0)
|
||||
while (inFile.eof() == 0)
|
||||
{
|
||||
int num, samples;
|
||||
|
||||
// Read sample data from input file
|
||||
num = inFile->read(sampleBuffer, readSize);
|
||||
const int num = inFile.read(sampleBuffer, readSize);
|
||||
|
||||
// Enter the new samples to the bpm analyzer class
|
||||
samples = num / nChannels;
|
||||
const int samples = num / nChannels;
|
||||
bpm.inputSamples(sampleBuffer, samples);
|
||||
}
|
||||
|
||||
// Now the whole song data has been analyzed. Read the resulting bpm.
|
||||
bpmValue = bpm.getBpm();
|
||||
const float bpmValue = bpm.getBpm();
|
||||
fprintf(stderr, "Done!\n");
|
||||
|
||||
// rewind the file after bpm detection
|
||||
inFile->rewind();
|
||||
inFile.rewind();
|
||||
|
||||
if (bpmValue > 0)
|
||||
{
|
||||
@ -262,61 +248,64 @@ static void detectBPM(WavInFile *inFile, RunParameters *params)
|
||||
return;
|
||||
}
|
||||
|
||||
if (params->goalBPM > 0)
|
||||
if (params.goalBPM > 0)
|
||||
{
|
||||
// adjust tempo to given bpm
|
||||
params->tempoDelta = (params->goalBPM / bpmValue - 1.0f) * 100.0f;
|
||||
fprintf(stderr, "The file will be converted to %.1f BPM\n\n", params->goalBPM);
|
||||
params.tempoDelta = (params.goalBPM / bpmValue - 1.0f) * 100.0f;
|
||||
fprintf(stderr, "The file will be converted to %.1f BPM\n\n", params.goalBPM);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(const int nParams, const char * const paramStr[])
|
||||
void ss_main(RunParameters& params)
|
||||
{
|
||||
WavInFile *inFile;
|
||||
WavOutFile *outFile;
|
||||
RunParameters *params;
|
||||
unique_ptr<WavInFile> inFile;
|
||||
unique_ptr<WavOutFile> outFile;
|
||||
SoundTouch soundTouch;
|
||||
|
||||
fprintf(stderr, _helloText, SoundTouch::getVersionString());
|
||||
fprintf(stderr, _helloText, soundTouch.getVersionString());
|
||||
|
||||
try
|
||||
// Open input & output files
|
||||
openFiles(inFile, outFile, params);
|
||||
|
||||
if (params.detectBPM == true)
|
||||
{
|
||||
// Parse command line parameters
|
||||
params = new RunParameters(nParams, paramStr);
|
||||
// detect sound BPM (and adjust processing parameters
|
||||
// accordingly if necessary)
|
||||
detectBPM(*inFile, params);
|
||||
}
|
||||
|
||||
// Open input & output files
|
||||
openFiles(&inFile, &outFile, params);
|
||||
// Setup the 'SoundTouch' object for processing the sound
|
||||
setup(soundTouch, *inFile, params);
|
||||
|
||||
if (params->detectBPM == true)
|
||||
{
|
||||
// detect sound BPM (and adjust processing parameters
|
||||
// accordingly if necessary)
|
||||
detectBPM(inFile, params);
|
||||
}
|
||||
|
||||
// Setup the 'SoundTouch' object for processing the sound
|
||||
setup(&soundTouch, inFile, params);
|
||||
|
||||
// clock_t cs = clock(); // for benchmarking processing duration
|
||||
// Process the sound
|
||||
process(&soundTouch, inFile, outFile);
|
||||
// clock_t ce = clock(); // for benchmarking processing duration
|
||||
// printf("duration: %lf\n", (double)(ce-cs)/CLOCKS_PER_SEC);
|
||||
|
||||
// Close WAV file handles & dispose of the objects
|
||||
delete inFile;
|
||||
delete outFile;
|
||||
delete params;
|
||||
|
||||
fprintf(stderr, "Done!\n");
|
||||
}
|
||||
catch (const runtime_error &e)
|
||||
// clock_t cs = clock(); // for benchmarking processing duration
|
||||
// Process the sound
|
||||
if (inFile && outFile)
|
||||
{
|
||||
process(soundTouch, *inFile, *outFile);
|
||||
}
|
||||
// clock_t ce = clock(); // for benchmarking processing duration
|
||||
// printf("duration: %lf\n", (double)(ce-cs)/CLOCKS_PER_SEC);
|
||||
|
||||
fprintf(stderr, "Done!\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if _WIN32
|
||||
int wmain(int argc, const wchar_t* args[])
|
||||
#else
|
||||
int main(int argc, const char* args[])
|
||||
#endif
|
||||
{
|
||||
try
|
||||
{
|
||||
soundstretch::RunParameters params(argc, args);
|
||||
soundstretch::ss_main(params);
|
||||
}
|
||||
catch (const runtime_error& e)
|
||||
{
|
||||
// An exception occurred during processing, display an error message
|
||||
fprintf(stderr, "%s\n", e.what());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -28,25 +28,25 @@
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@ -134,10 +134,7 @@
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<MapFileName>$(OutDir)$(TargetName).map</MapFileName>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention />
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>if not exist ..\..\bin mkdir ..\..\bin
|
||||
@ -183,9 +180,7 @@ copy $(OutDir)$(TargetName)$(TargetExt) ..\..\bin\</Command>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<MapFileName>$(OutDir)$(TargetName).map</MapFileName>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention />
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>if not exist ..\..\bin mkdir ..\..\bin
|
||||
@ -234,9 +229,7 @@ copy $(OutDir)$(TargetName)$(TargetExt) ..\..\bin\</Command>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<MapFileName>$(OutDir)$(TargetName).map</MapFileName>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention />
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>if not exist ..\..\bin mkdir ..\..\bin
|
||||
@ -284,9 +277,7 @@ copy $(OutDir)$(TargetName)$(TargetExt) ..\..\bin\</Command>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<MapFileName>$(OutDir)$(TargetName).map</MapFileName>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention />
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>if not exist ..\..\bin mkdir ..\..\bin
|
||||
@ -327,6 +318,7 @@ copy $(OutDir)$(TargetName)$(TargetExt) ..\..\bin\</Command>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="RunParameters.h" />
|
||||
<ClInclude Include="SS_CharTypes.h" />
|
||||
<ClInclude Include="WavFile.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -27,25 +27,25 @@
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
@ -16,9 +16,10 @@
|
||||
#include "../../SoundStretch/WavFile.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace soundstretch;
|
||||
|
||||
// DllTest main
|
||||
int main(int argc, char *argv[])
|
||||
int wmain(int argc, const wchar_t *argv[])
|
||||
{
|
||||
// Check program arguments
|
||||
if (argc < 4)
|
||||
@ -27,22 +28,22 @@ int main(int argc, char *argv[])
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *inFileName = argv[1];
|
||||
const char *outFileName = argv[2];
|
||||
string str_sampleType = argv[3];
|
||||
wstring inFileName = argv[1];
|
||||
wstring outFileName = argv[2];
|
||||
wstring str_sampleType = argv[3];
|
||||
|
||||
bool floatSample;
|
||||
if (str_sampleType.compare("float") == 0)
|
||||
if (str_sampleType == L"float")
|
||||
{
|
||||
floatSample = true;
|
||||
}
|
||||
else if (str_sampleType.compare("short") == 0)
|
||||
else if (str_sampleType == L"short")
|
||||
{
|
||||
floatSample = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Missing or invalid sampletype '" << str_sampleType << "'. Expected either short or float" << endl;
|
||||
cerr << "Missing or invalid sampletype. Expected either short or float" << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -69,12 +69,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "Comments", "SoundTouch Library licensed for 3rd party applications subject to LGPL license v2.1. Visit http://www.surina.net/soundtouch for more information about the SoundTouch library."
|
||||
VALUE "FileDescription", "SoundTouch Dynamic Link Library"
|
||||
VALUE "FileVersion", "2.3.2.0"
|
||||
VALUE "FileVersion", "2.3.3.0"
|
||||
VALUE "InternalName", "SoundTouch"
|
||||
VALUE "LegalCopyright", "Copyright (C) Olli Parviainen 2023"
|
||||
VALUE "LegalCopyright", "Copyright (C) Olli Parviainen 2024"
|
||||
VALUE "OriginalFilename", "SoundTouch.dll"
|
||||
VALUE "ProductName", " SoundTouch Dynamic Link Library"
|
||||
VALUE "ProductVersion", "2.3.2.0"
|
||||
VALUE "ProductVersion", "2.3.3.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
@ -27,22 +27,22 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
Loading…
Reference in New Issue
Block a user