From c8ebbdc00f339e463509b9eb1d4bf3754b8ed370 Mon Sep 17 00:00:00 2001 From: "gregory.hainaut@gmail.com" Date: Sun, 12 Dec 2010 11:08:04 +0000 Subject: [PATCH] zerospu2: Use local copy of wavfile like spu2x git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4089 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/zerospu2/CMakeLists.txt | 2 + plugins/zerospu2/WavFile.cpp | 149 ++++++++++++++++++++++++++++++++ plugins/zerospu2/WavFile.h | 113 ++++++++++++++++++++++++ plugins/zerospu2/zerospu2.cpp | 4 + plugins/zerospu2/zeroworker.cpp | 4 + 5 files changed, 272 insertions(+) create mode 100644 plugins/zerospu2/WavFile.cpp create mode 100644 plugins/zerospu2/WavFile.h diff --git a/plugins/zerospu2/CMakeLists.txt b/plugins/zerospu2/CMakeLists.txt index 02c439eec..c72f4db79 100644 --- a/plugins/zerospu2/CMakeLists.txt +++ b/plugins/zerospu2/CMakeLists.txt @@ -40,6 +40,7 @@ endif(CMAKE_BUILD_TYPE STREQUAL Release) # zerospu2 sources set(zerospu2Sources voices.cpp + WavFile.cpp zerodma.cpp zerospu2.cpp zeroworker.cpp) @@ -48,6 +49,7 @@ set(zerospu2Sources set(zerospu2Headers misc.h reg.h + WavFile.h zerodma.h zerospu2.h zeroworker.h) diff --git a/plugins/zerospu2/WavFile.cpp b/plugins/zerospu2/WavFile.cpp new file mode 100644 index 000000000..30c0988e8 --- /dev/null +++ b/plugins/zerospu2/WavFile.cpp @@ -0,0 +1,149 @@ +/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2 + * Developed and maintained by the Pcsx2 Development Team. + * + * The file is based on WavFile.h from SoundTouch library. + * Original portions are (c) 2009 by Olli Parviainen (oparviai 'at' iki.fi) + * + * SPU2-X 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X 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 SPU2-X. If not, see . + */ + +// Note the file is mostly a copy paste of the WavFile.h from SoundTouch library. It was +// shrunken to support only output 16 bits wav files + +#include +#include +#include +#include +#include +#include + +#include "WavFile.h" + +using namespace std; + +static const char riffStr[] = "RIFF"; +static const char waveStr[] = "WAVE"; +static const char fmtStr[] = "fmt "; +static const char dataStr[] = "data"; + +////////////////////////////////////////////////////////////////////////////// +// +// Class WavOutFile +// + +WavOutFile::WavOutFile(const char *fileName, int sampleRate, int bits, int channels) +{ + bytesWritten = 0; + fptr = fopen(fileName, "wb"); + if (fptr == NULL) + { + string msg = "Error : Unable to open file \""; + msg += fileName; + msg += "\" for writing."; + //pmsg = msg.c_str; + throw runtime_error(msg); + } + + fillInHeader(sampleRate, bits, channels); + writeHeader(); +} + + +WavOutFile::~WavOutFile() +{ + finishHeader(); + if (fptr) fclose(fptr); + fptr = NULL; +} + + + +void WavOutFile::fillInHeader(uint sampleRate, uint bits, uint channels) +{ + // fill in the 'riff' part.. + + // copy string 'RIFF' to riff_char + memcpy(&(header.riff.riff_char), riffStr, 4); + // package_len unknown so far + header.riff.package_len = 0; + // copy string 'WAVE' to wave + memcpy(&(header.riff.wave), waveStr, 4); + + + // fill in the 'format' part.. + + // copy string 'fmt ' to fmt + memcpy(&(header.format.fmt), fmtStr, 4); + + header.format.format_len = 0x10; + header.format.fixed = 1; + header.format.channel_number = (short)channels; + header.format.sample_rate = (int)sampleRate; + header.format.bits_per_sample = (short)bits; + header.format.byte_per_sample = (short)(bits * channels / 8); + header.format.byte_rate = header.format.byte_per_sample * (int)sampleRate; + header.format.sample_rate = (int)sampleRate; + + // fill in the 'data' part.. + + // copy string 'data' to data_field + memcpy(&(header.data.data_field), dataStr, 4); + // data_len unknown so far + header.data.data_len = 0; +} + + +void WavOutFile::finishHeader() +{ + // supplement the file length into the header structure + header.riff.package_len = bytesWritten + 36; + header.data.data_len = bytesWritten; + + writeHeader(); +} + + + +void WavOutFile::writeHeader() +{ + int res; + + // write the supplemented header in the beginning of the file + fseek(fptr, 0, SEEK_SET); + res = fwrite(&header, sizeof(header), 1, fptr); + if (res != 1) + { + throw runtime_error("Error while writing to a wav file."); + } + + // jump back to the end of the file + fseek(fptr, 0, SEEK_END); +} + + +void WavOutFile::write(const short *buffer, int numElems) +{ + int res; + + // 16bit format & 16 bit samples + + assert(header.format.bits_per_sample == 16); + if (numElems < 1) return; // nothing to do + + res = fwrite(buffer, 2, numElems, fptr); + + if (res != numElems) + { + throw runtime_error("Error while writing to a wav file."); + } + bytesWritten += 2 * numElems; +} diff --git a/plugins/zerospu2/WavFile.h b/plugins/zerospu2/WavFile.h new file mode 100644 index 000000000..7d75c4bac --- /dev/null +++ b/plugins/zerospu2/WavFile.h @@ -0,0 +1,113 @@ +/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2 + * Developed and maintained by the Pcsx2 Development Team. + * + * The file is based on WavFile.h from SoundTouch library. + * Original portions are (c) 2009 by Olli Parviainen (oparviai 'at' iki.fi) + * + * SPU2-X 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X 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 SPU2-X. If not, see . + */ + +// Note the file is mostly a copy paste of the WavFile.h from SoundTouch library. It was +// shrunken to support only output 16 bits wav files + +#ifndef WAVFILE_H +#define WAVFILE_H + +#include + +#ifndef uint +typedef unsigned int uint; +#endif + + +/// WAV audio file 'riff' section header +typedef struct +{ + char riff_char[4]; + int package_len; + char wave[4]; +} WavRiff; + +/// WAV audio file 'format' section header +typedef struct +{ + char fmt[4]; + int format_len; + short fixed; + short channel_number; + int sample_rate; + int byte_rate; + short byte_per_sample; + short bits_per_sample; +} WavFormat; + +/// WAV audio file 'data' section header +typedef struct +{ + char data_field[4]; + uint data_len; +} WavData; + + +/// WAV audio file header +typedef struct +{ + WavRiff riff; + WavFormat format; + WavData data; +} WavHeader; + + +/// Class for writing WAV audio files. +class WavOutFile +{ +private: + /// Pointer to the WAV file + FILE *fptr; + + /// WAV file header data. + WavHeader header; + + /// Counter of how many bytes have been written to the file so far. + int bytesWritten; + + /// Fills in WAV file header information. + void fillInHeader(const uint sampleRate, const uint bits, const uint channels); + + /// Finishes the WAV file header by supplementing information of amount of + /// data written to file etc + void finishHeader(); + + /// Writes the WAV file header. + void writeHeader(); + +public: + /// Constructor: Creates a new WAV file. Throws a 'runtime_error' exception + /// if file creation fails. + WavOutFile(const char *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) + ); + + /// Destructor: Finalizes & closes the WAV file. + ~WavOutFile(); + + /// Write data to WAV file. Throws a 'runtime_error' exception if writing to + /// file fails. + void write(const short *buffer, ///< Pointer to sample data buffer. + int numElems ///< How many array items are to be written to file. + ); + +}; + +#endif diff --git a/plugins/zerospu2/zerospu2.cpp b/plugins/zerospu2/zerospu2.cpp index 363ba8e8f..3e8c4d6e8 100644 --- a/plugins/zerospu2/zerospu2.cpp +++ b/plugins/zerospu2/zerospu2.cpp @@ -28,7 +28,11 @@ #include #include "soundtouch/SoundTouch.h" +#ifdef __LINUX__ +#include "WavFile.h" +#else #include "soundtouch/WavFile.h" +#endif char libraryName[256]; diff --git a/plugins/zerospu2/zeroworker.cpp b/plugins/zerospu2/zeroworker.cpp index 01b3ffaf8..41a2dfeeb 100644 --- a/plugins/zerospu2/zeroworker.cpp +++ b/plugins/zerospu2/zeroworker.cpp @@ -19,7 +19,11 @@ #include "zerospu2.h" #include "zeroworker.h" #include "soundtouch/SoundTouch.h" +#ifdef __LINUX__ +#include "WavFile.h" +#else #include "soundtouch/WavFile.h" +#endif s32 g_logsound = 0; WavOutFile* g_pWavRecord=NULL; // used for recording