mirror of
https://github.com/RPCS3/soundtouch.git
synced 2025-02-25 04:42:12 +00:00
Allow using standard input/output pipes for processing
This commit is contained in:
parent
eb4c84fb14
commit
c7bbaa4dbe
1399
README.html
1399
README.html
File diff suppressed because it is too large
Load Diff
@ -77,7 +77,10 @@ static const char whatText[] =
|
||||
|
||||
static const char usage[] =
|
||||
"Usage :\n"
|
||||
" soundstretch infile.wav outfile.wav [switches]\n\n"
|
||||
" soundstretch infilename outfilename [switches]\n"
|
||||
"\n"
|
||||
"To use standard input/output pipes, give 'stdin' and 'stdout' as filenames.\n"
|
||||
"\n"
|
||||
"Available switches are:\n"
|
||||
" -tempo=n : Change sound tempo by n percents (n=-95..+5000 %)\n"
|
||||
" -pitch=n : Change sound pitch by n semitones (n=-60..+60 semitones)\n"
|
||||
|
@ -140,8 +140,6 @@ const static char dataStr[] = "data";
|
||||
|
||||
WavInFile::WavInFile(const char *fileName)
|
||||
{
|
||||
int hdrsOk;
|
||||
|
||||
// Try to open the file for reading
|
||||
fptr = fopen(fileName, "rb");
|
||||
if (fptr == NULL)
|
||||
@ -153,22 +151,45 @@ WavInFile::WavInFile(const char *fileName)
|
||||
throw runtime_error(msg);
|
||||
}
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
WavInFile::WavInFile(FILE *file)
|
||||
{
|
||||
// Try to open the file for reading
|
||||
fptr = file;
|
||||
if (!file)
|
||||
{
|
||||
// didn't succeed
|
||||
string msg = "Error : Unable to access input stream for reading";
|
||||
throw runtime_error(msg);
|
||||
}
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
/// Init the WAV file stream
|
||||
void WavInFile::init()
|
||||
{
|
||||
int hdrsOk;
|
||||
|
||||
// assume file stream is already open
|
||||
assert(fptr);
|
||||
|
||||
// Read the file headers
|
||||
hdrsOk = readWavHeaders();
|
||||
if (hdrsOk != 0)
|
||||
{
|
||||
// Something didn't match in the wav file headers
|
||||
string msg = "File \"";
|
||||
msg += fileName;
|
||||
msg += "\" is corrupt or not a WAV file";
|
||||
string msg = "Input file is corrupt or not a WAV file";
|
||||
throw runtime_error(msg);
|
||||
}
|
||||
|
||||
if (header.format.fixed != 1)
|
||||
{
|
||||
string msg = "File \"";
|
||||
msg += fileName;
|
||||
msg += "\" uses unsupported encoding.";
|
||||
string msg = "Input file uses unsupported encoding.";
|
||||
throw runtime_error(msg);
|
||||
}
|
||||
|
||||
@ -537,6 +558,21 @@ WavOutFile::WavOutFile(const char *fileName, int sampleRate, int bits, int chann
|
||||
}
|
||||
|
||||
|
||||
WavOutFile::WavOutFile(FILE *file, int sampleRate, int bits, int channels)
|
||||
{
|
||||
bytesWritten = 0;
|
||||
fptr = file;
|
||||
if (fptr == NULL)
|
||||
{
|
||||
string msg = "Error : Unable to access output file stream.";
|
||||
throw runtime_error(msg);
|
||||
}
|
||||
|
||||
fillInHeader(sampleRate, bits, channels);
|
||||
writeHeader();
|
||||
}
|
||||
|
||||
|
||||
|
||||
WavOutFile::~WavOutFile()
|
||||
{
|
||||
|
@ -105,6 +105,9 @@ private:
|
||||
/// WAV header information
|
||||
WavHeader header;
|
||||
|
||||
/// Init the WAV file stream
|
||||
void init();
|
||||
|
||||
/// Read WAV file headers.
|
||||
/// \return zero if all ok, nonzero if file format is invalid.
|
||||
int readWavHeaders();
|
||||
@ -125,6 +128,8 @@ public:
|
||||
/// throws 'runtime_error' exception.
|
||||
WavInFile(const char *filename);
|
||||
|
||||
WavInFile(FILE *file);
|
||||
|
||||
/// Destructor: Closes the file.
|
||||
~WavInFile();
|
||||
|
||||
@ -222,6 +227,8 @@ public:
|
||||
int channels ///< Number of channels (1=mono, 2=stereo)
|
||||
);
|
||||
|
||||
WavOutFile(FILE *file, int sampleRate, int bits, int channels);
|
||||
|
||||
/// Destructor: Finalizes & closes the WAV file.
|
||||
~WavOutFile();
|
||||
|
||||
|
@ -49,12 +49,25 @@ using namespace std;
|
||||
// Processing chunk size
|
||||
#define BUFF_SIZE 2048
|
||||
|
||||
#if WIN32
|
||||
#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))
|
||||
#else
|
||||
// Not needed for GNU environment... ?
|
||||
#define SET_STREAM_TO_BIN_MODE(f) ()
|
||||
#endif
|
||||
|
||||
|
||||
static const char _helloText[] =
|
||||
"\n"
|
||||
" SoundStretch v%s - Written by Olli Parviainen 2001 - 2008\n"
|
||||
"==================================================================\n"
|
||||
"author e-mail: <oparviai@iki.fi> - WWW: http://www.surina.net/soundtouch\n"
|
||||
"author e-mail: <oparviai"
|
||||
"@"
|
||||
"iki.fi> - WWW: http://www.surina.net/soundtouch\n"
|
||||
"\n"
|
||||
"This program is subject to (L)GPL license. Run \"soundstretch -license\" for\n"
|
||||
"more information.\n"
|
||||
@ -64,8 +77,17 @@ static void openFiles(WavInFile **inFile, WavOutFile **outFile, const RunParamet
|
||||
{
|
||||
int bits, samplerate, channels;
|
||||
|
||||
// open input file...
|
||||
*inFile = new WavInFile(params->inFileName);
|
||||
if (strcmp(params->inFileName, "stdin") == 0)
|
||||
{
|
||||
// used 'stdin' as input file
|
||||
SET_STREAM_TO_BIN_MODE(stdin);
|
||||
*inFile = new WavInFile(stdin);
|
||||
}
|
||||
else
|
||||
{
|
||||
// open input file...
|
||||
*inFile = new WavInFile(params->inFileName);
|
||||
}
|
||||
|
||||
// ... open output file with same sound parameters
|
||||
bits = (*inFile)->getNumBits();
|
||||
@ -74,7 +96,15 @@ static void openFiles(WavInFile **inFile, WavOutFile **outFile, const RunParamet
|
||||
|
||||
if (params->outFileName)
|
||||
{
|
||||
*outFile = new WavOutFile(params->outFileName, samplerate, bits, channels);
|
||||
if (strcmp(params->outFileName, "stdout") == 0)
|
||||
{
|
||||
SET_STREAM_TO_BIN_MODE(stdout);
|
||||
*outFile = new WavOutFile(stdout, samplerate, bits, channels);
|
||||
}
|
||||
else
|
||||
{
|
||||
*outFile = new WavOutFile(params->outFileName, samplerate, bits, channels);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -107,27 +137,27 @@ static void setup(SoundTouch *pSoundTouch, const WavInFile *inFile, const RunPar
|
||||
if (params->outFileName)
|
||||
{
|
||||
#ifdef INTEGER_SAMPLES
|
||||
printf("Uses 16bit integer sample type in processing.\n\n");
|
||||
fprintf(stderr, "Uses 16bit integer sample type in processing.\n\n");
|
||||
#else
|
||||
#ifndef FLOAT_SAMPLES
|
||||
#error "Sampletype not defined"
|
||||
#endif
|
||||
printf("Uses 32bit floating point sample type in processing.\n\n");
|
||||
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
|
||||
printf("Processing the file with the following changes:\n");
|
||||
printf(" tempo change = %+g %%\n", params->tempoDelta);
|
||||
printf(" pitch change = %+g semitones\n", params->pitchDelta);
|
||||
printf(" rate change = %+g %%\n\n", params->rateDelta);
|
||||
printf("Working...");
|
||||
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, "Working...");
|
||||
}
|
||||
else
|
||||
{
|
||||
// outFileName not given
|
||||
printf("Warning: output file name missing, won't output anything.\n\n");
|
||||
fprintf(stderr, "Warning: output file name missing, won't output anything.\n\n");
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
|
||||
@ -194,8 +224,8 @@ static void detectBPM(WavInFile *inFile, RunParameters *params)
|
||||
SAMPLETYPE sampleBuffer[BUFF_SIZE];
|
||||
|
||||
// detect bpm rate
|
||||
printf("Detecting BPM rate...");
|
||||
fflush(stdout);
|
||||
fprintf(stderr, "Detecting BPM rate...");
|
||||
fflush(stderr);
|
||||
|
||||
nChannels = inFile->getNumChannels();
|
||||
|
||||
@ -215,18 +245,18 @@ static void detectBPM(WavInFile *inFile, RunParameters *params)
|
||||
|
||||
// Now the whole song data has been analyzed. Read the resulting bpm.
|
||||
bpmValue = bpm.getBpm();
|
||||
printf("Done!\n");
|
||||
fprintf(stderr, "Done!\n");
|
||||
|
||||
// rewind the file after bpm detection
|
||||
inFile->rewind();
|
||||
|
||||
if (bpmValue > 0)
|
||||
{
|
||||
printf("Detected BPM rate %.1f\n\n", bpmValue);
|
||||
fprintf(stderr, "Detected BPM rate %.1f\n\n", bpmValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Couldn't detect BPM rate.\n\n");
|
||||
fprintf(stderr, "Couldn't detect BPM rate.\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -234,7 +264,7 @@ static void detectBPM(WavInFile *inFile, RunParameters *params)
|
||||
{
|
||||
// adjust tempo to given bpm
|
||||
params->tempoDelta = (params->goalBPM / bpmValue - 1.0f) * 100.0f;
|
||||
printf("The file will be converted to %.1f BPM\n\n", params->goalBPM);
|
||||
fprintf(stderr, "The file will be converted to %.1f BPM\n\n", params->goalBPM);
|
||||
}
|
||||
}
|
||||
|
||||
@ -247,7 +277,7 @@ int main(const int nParams, const char *paramStr[])
|
||||
RunParameters *params;
|
||||
SoundTouch SoundTouch;
|
||||
|
||||
printf(_helloText, SoundTouch::getVersionString());
|
||||
fprintf(stderr, _helloText, SoundTouch::getVersionString());
|
||||
|
||||
try
|
||||
{
|
||||
@ -275,12 +305,12 @@ int main(const int nParams, const char *paramStr[])
|
||||
delete outFile;
|
||||
delete params;
|
||||
|
||||
printf("Done!\n");
|
||||
fprintf(stderr, "Done!\n");
|
||||
}
|
||||
catch (runtime_error &e)
|
||||
{
|
||||
// An exception occurred during processing, display an error message
|
||||
printf("%s\n", e.what());
|
||||
fprintf(stderr, "%s\n", e.what());
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user