M src/AudioWriteStreamFactory.cpp +8 -1
@@ 60,7 60,7 @@ AudioWriteStreamFactory::createWriteStre
AudioWriteStreamFactoryImpl *f = AudioWriteStreamFactoryImpl::getInstance();
- if (extension == "") {
+ if (extension == "" || extension.size() > 4) {
// We explicitly support extension-less filenames and write
// them in RIFF/WAVE format. (This is in order to support
// programmatically generated temporary files created with
@@ 141,8 141,15 @@ AudioWriteStreamFactory::isExtensionSupp
// #ifdef'd out if the implementation is not selected, so there is no
// overhead.
+// WavFileWriteStream uses libsndfile, which is mostly trustworthy
#include "WavFileWriteStream.cpp"
+
+// SimpleWavFileWriteStream writes only 24-bit WAV files. The
+// dedicated WavFileReadStream using libsndfile is generally much
+// better and goes first
#include "SimpleWavFileWriteStream.cpp"
+
#include "CoreAudioWriteStream.cpp"
+
#include "OpusWriteStream.cpp"
M src/OpusWriteStream.cpp +3 -1
@@ 33,6 33,7 @@
*/
#ifdef HAVE_OPUS
+#ifndef HAVE_OPUS_READ_ONLY
//#define DEBUG_OPUS_WRITE 1
@@ 157,4 158,5 @@ OpusWriteStream::putInterleavedFrames(si
}
-#endif
+#endif // !HAVE_OPUS_READ_ONLY
+#endif // HAVE_OPUS
M src/OpusWriteStream.h +3 -1
@@ 38,6 38,7 @@
#include "../bqaudiostream/AudioWriteStream.h"
#ifdef HAVE_OPUS
+#ifndef HAVE_OPUS_READ_ONLY
namespace breakfastquay
{
@@ 61,6 62,7 @@ protected:
}
-#endif
+#endif // !HAVE_OPUS_READ_ONLY
+#endif // HAVE_OPUS
#endif
M src/SimpleWavFileReadStream.cpp +18 -3
@@ 68,9 68,24 @@ SimpleWavFileReadStream::SimpleWavFileRe
m_dataReadStart(0),
m_retryCount(0)
{
- m_file = new std::ifstream(filename.c_str(),
- std::ios::in | std::ios::binary);
-
+#ifdef _MSC_VER
+ // This is behind _MSC_VER not _WIN32 because the fstream
+ // constructors from wchar bufs are an MSVC extension not
+ // available in e.g. MinGW
+ int wlen = MultiByteToWideChar
+ (CP_UTF8, 0, m_path.c_str(), m_path.length(), 0, 0);
+ if (wlen > 0) {
+ wchar_t *buf = new wchar_t[wlen+1];
+ (void)MultiByteToWideChar
+ (CP_UTF8, 0, m_path.c_str(), m_path.length(), buf, wlen);
+ buf[wlen] = L'\0';
+ m_file = new std::ifstream(buf, std::ios::in | std::ios::binary);
+ delete[] buf;
+ }
+#else
+ m_file = new std::ifstream(m_path.c_str(), std::ios::in | std::ios::binary);
+#endif
+
if (!*m_file) {
delete m_file;
m_file = 0;
M src/SimpleWavFileReadStream.h +4 -0
@@ 37,6 37,10 @@
#include "../bqaudiostream/AudioReadStream.h"
+#ifdef _MSC_VER
+#include <windows.h>
+#endif
+
#include <fstream>
#include <string>
#include <vector>
M src/SimpleWavFileWriteStream.cpp +31 -10
@@ 62,14 62,32 @@ SimpleWavFileWriteStream::SimpleWavFileW
m_bitDepth(24),
m_file(0)
{
- m_file = new std::ofstream(getPath().c_str(), std::ios::out | std::ios::binary);
+ std::string path = getPath();
+
+#ifdef _MSC_VER
+ // This is behind _MSC_VER not _WIN32 because the fstream
+ // constructors from wchar bufs are an MSVC extension not
+ // available in e.g. MinGW
+ int wlen = MultiByteToWideChar
+ (CP_UTF8, 0, path.c_str(), path.length(), 0, 0);
+ if (wlen > 0) {
+ wchar_t *buf = new wchar_t[wlen+1];
+ (void)MultiByteToWideChar
+ (CP_UTF8, 0, path.c_str(), path.length(), buf, wlen);
+ buf[wlen] = L'\0';
+ m_file = new std::ofstream(buf, std::ios::out | std::ios::binary);
+ delete[] buf;
+ }
+#else
+ m_file = new std::ofstream(path.c_str(), std::ios::out | std::ios::binary);
+#endif
if (!*m_file) {
delete m_file;
m_file = 0;
m_error = std::string("Failed to open audio file '") +
- getPath() + "' for writing";
- throw FailedToWriteFile(getPath());
+ path + "' for writing";
+ throw FailedToWriteFile(path);
}
writeFormatChunk();
@@ 96,19 114,24 @@ SimpleWavFileWriteStream::~SimpleWavFile
}
m_file->seekp(0, std::ios::end);
- uint32_t totalSize = m_file->tellp();
+
+ std::streamoff totalSize = m_file->tellp();
+ uint32_t effSize = uint32_t(-1);
+ if (totalSize < std::streamoff(effSize)) {
+ effSize = uint32_t(totalSize);
+ }
// seek to first length position
m_file->seekp(4, std::ios::beg);
// write complete file size minus 8 bytes to here
- putBytes(int2le(totalSize - 8, 4));
+ putBytes(int2le(effSize - 8, 4));
// reseek from start forward 40
m_file->seekp(40, std::ios::beg);
// write the data chunk size to end
- putBytes(int2le(totalSize - 44, 4));
+ putBytes(int2le(effSize - 44, 4));
m_file->close();
@@ 117,12 140,10 @@ SimpleWavFileWriteStream::~SimpleWavFile
}
void
-SimpleWavFileWriteStream::putBytes(std::string s)
+SimpleWavFileWriteStream::putBytes(const std::string &s)
{
if (!m_file) return;
- for (uint32_t i = 0; i < s.length(); i++) {
- *m_file << (uint8_t)s[i];
- }
+ m_file->write(s.data(), s.length());
}
void
M src/SimpleWavFileWriteStream.h +5 -1
@@ 37,6 37,10 @@
#include "../bqaudiostream/AudioWriteStream.h"
+#ifdef _MSC_VER
+#include <windows.h>
+#endif
+
#include <fstream>
#include <string>
@@ 59,7 63,7 @@ protected:
std::ofstream *m_file;
void writeFormatChunk();
- void putBytes(std::string);
+ void putBytes(const std::string &);
void putBytes(const unsigned char *, size_t);
};
M src/WavFileWriteStream.cpp +17 -3
@@ 66,12 66,26 @@ WavFileWriteStream::WavFileWriteStream(T
m_fileInfo.channels = getChannelCount();
m_fileInfo.samplerate = getSampleRate();
- m_file = sf_open(getPath().c_str(), SFM_WRITE, &m_fileInfo);
+ auto path = getPath();
+#ifdef _WIN32
+ int wlen = MultiByteToWideChar
+ (CP_UTF8, 0, path.c_str(), path.length(), 0, 0);
+ if (wlen > 0) {
+ wchar_t *buf = new wchar_t[wlen+1];
+ (void)MultiByteToWideChar
+ (CP_UTF8, 0, path.c_str(), path.length(), buf, wlen);
+ buf[wlen] = L'\0';
+ m_file = sf_wchar_open(buf, SFM_WRITE, &m_fileInfo);
+ delete[] buf;
+ }
+#else
+ m_file = sf_open(path.c_str(), SFM_WRITE, &m_fileInfo);
+#endif
if (!m_file) {
m_error = std::string("Failed to open audio file '") +
- getPath() + "' for writing";
- throw FailedToWriteFile(getPath());
+ path + "' for writing";
+ throw FailedToWriteFile(path);
}
}
M src/WavFileWriteStream.h +5 -0
@@ 39,6 39,11 @@
#if defined(HAVE_LIBSNDFILE) || defined(HAVE_SNDFILE)
+#ifdef _WIN32
+#include <windows.h>
+#define ENABLE_SNDFILE_WINDOWS_PROTOTYPES 1
+#endif
+
#include <sndfile.h>
namespace breakfastquay