Result SoundSourceSndFile::open() { #ifdef __WINDOWS__ // Pointer valid until string changed LPCWSTR lpcwFilename = (LPCWSTR)getFilename().utf16(); fh = sf_wchar_open(lpcwFilename, SFM_READ, &info); #else const QByteArray qbaFilename(getFilename().toLocal8Bit()); fh = sf_open(qbaFilename.constData(), SFM_READ, &info); #endif if (fh == NULL) { // sf_format_check is only for writes qWarning() << "libsndfile: Error opening file" << getFilename() << sf_strerror(fh); return ERR; } if (sf_error(fh)>0) { qWarning() << "libsndfile: Error opening file" << getFilename() << sf_strerror(fh); return ERR; } channels = info.channels; setSampleRate(info.samplerate); // This is the 'virtual' filelength. No matter how many channels the file // actually has, we pretend it has 2. filelength = info.frames * 2; // File length with two interleaved channels return OK; }
static void wchar_test (void) { #if OS_IS_WIN32 SNDFILE * file ; SF_INFO info ; LPCWSTR filename = L"test.wav" ; print_test_name (__func__, "test.wav") ; info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ; info.channels = 1 ; info.samplerate = 44100 ; file = sf_wchar_open (filename, SFM_WRITE, &info) ; exit_if_true (file == NULL, "\n\nLine %d : sf_wchar_open failed : %s\n\n", __LINE__, sf_strerror (NULL)) ; sf_close (file) ; /* This should check that the file did in fact get created with a ** wchar_t * filename. */ exit_if_true ( GetFileAttributesW (filename) == INVALID_FILE_ATTRIBUTES, "\n\nLine %d : GetFileAttributes failed.\n\n", __LINE__ ) ; /* Use this because the file was created with CreateFileW. */ DeleteFileW (filename) ; puts ("ok") ; #endif } /* wchar_test */
Result SoundSourceSndFile::tryOpen(const AudioSourceConfig& /*audioSrcCfg*/) { DEBUG_ASSERT(!m_pSndFile); SF_INFO sfInfo; #ifdef __WINDOWS__ // Pointer valid until string changed const QString fileName(getLocalFileName()); LPCWSTR lpcwFilename = (LPCWSTR) fileName.utf16(); m_pSndFile = sf_wchar_open(lpcwFilename, SFM_READ, &sfInfo); #else memset(&sfInfo, 0, sizeof(sfInfo)); m_pSndFile = sf_open(getLocalFileNameBytes().constData(), SFM_READ, &sfInfo); #endif if (!m_pSndFile) { // sf_format_check is only for writes qWarning() << "Error opening libsndfile file:" << getUrlString() << sf_strerror(m_pSndFile); return ERR; } if (sf_error(m_pSndFile) > 0) { qWarning() << "Error opening libsndfile file:" << getUrlString() << sf_strerror(m_pSndFile); return ERR; } setChannelCount(sfInfo.channels); setFrameRate(sfInfo.samplerate); setFrameCount(sfInfo.frames); return OK; }
SNDFILE* sf_openx(const char *path, int mode, SF_INFO *sfinfo) { int size; wchar_t *wp; size = MultiByteToWideChar(65001, 0, path, -1, 0, 0); wp = _alloca(size * sizeof(wchar_t)); size = MultiByteToWideChar(65001, 0, path, -1, wp, size); return sf_wchar_open(wp, mode, sfinfo); }
SoundSource::OpenResult SoundSourceSndFile::tryOpen(const AudioSourceConfig& /*audioSrcCfg*/) { DEBUG_ASSERT(!m_pSndFile); SF_INFO sfInfo; memset(&sfInfo, 0, sizeof(sfInfo)); #ifdef __WINDOWS__ // Note: we cannot use QString::toStdWString since QT 4 is compiled with // '/Zc:wchar_t-' flag and QT 5 not const QString localFileName(QDir::toNativeSeparators(getLocalFileName())); const ushort* const fileNameUtf16 = localFileName.utf16(); static_assert(sizeof(wchar_t) == sizeof(ushort), "QString::utf16(): wchar_t and ushort have different sizes"); m_pSndFile = sf_wchar_open( reinterpret_cast<wchar_t*>(const_cast<ushort*>(fileNameUtf16)), SFM_READ, &sfInfo); #else m_pSndFile = sf_open(getLocalFileName().toLocal8Bit(), SFM_READ, &sfInfo); #endif switch (sf_error(m_pSndFile)) { case SF_ERR_NO_ERROR: DEBUG_ASSERT(m_pSndFile != nullptr); break; // continue case SF_ERR_UNRECOGNISED_FORMAT: return OpenResult::UNSUPPORTED_FORMAT; default: const QString errorMsg(sf_strerror(m_pSndFile)); if (errorMsg.toLower().indexOf("unknown format") != -1) { // NOTE(uklotzde 2016-05-11): This actually happens when // trying to open a file with a supported file extension // that contains data in an unsupported format! return OpenResult::UNSUPPORTED_FORMAT; } else { qWarning() << "Error opening libsndfile file:" << getUrlString() << errorMsg; return OpenResult::FAILED; } } setChannelCount(sfInfo.channels); setSamplingRate(sfInfo.samplerate); setFrameCount(sfInfo.frames); return OpenResult::SUCCEEDED; }
Result SoundSourceSndFile::tryOpen(const AudioSourceConfig& /*audioSrcCfg*/) { DEBUG_ASSERT(!m_pSndFile); SF_INFO sfInfo; memset(&sfInfo, 0, sizeof(sfInfo)); #ifdef __WINDOWS__ // Note: we cannot use QString::toStdWString since QT 4 is compiled with // '/Zc:wchar_t-' flag and QT 5 not const QString localFileName(QDir::toNativeSeparators(getLocalFileName())); const ushort* const fileNameUtf16 = localFileName.utf16(); static_assert(sizeof(wchar_t) == sizeof(ushort), "QString::utf16(): wchar_t and ushort have different sizes"); m_pSndFile = sf_wchar_open( reinterpret_cast<wchar_t*>(const_cast<ushort*>(fileNameUtf16)), SFM_READ, &sfInfo); #else m_pSndFile = sf_open(getLocalFileName().toLocal8Bit(), SFM_READ, &sfInfo); #endif if (!m_pSndFile) { // sf_format_check is only for writes qWarning() << "Error opening libsndfile file:" << getUrlString() << sf_strerror(m_pSndFile); return ERR; } if (sf_error(m_pSndFile) > 0) { qWarning() << "Error opening libsndfile file:" << getUrlString() << sf_strerror(m_pSndFile); return ERR; } setChannelCount(sfInfo.channels); setSamplingRate(sfInfo.samplerate); setFrameCount(sfInfo.frames); return OK; }
bool EngineRecord::openFile() { // Unfortunately, we cannot use QFile for writing WAV and AIFF audio. if (m_encoding == ENCODING_WAVE || m_encoding == ENCODING_AIFF){ unsigned long samplerate = m_pSamplerate->get(); // set sfInfo m_sfInfo.samplerate = samplerate; m_sfInfo.channels = 2; if (m_encoding == ENCODING_WAVE) m_sfInfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; else m_sfInfo.format = SF_FORMAT_AIFF | SF_FORMAT_PCM_16; // Creates a new WAVE or AIFF file and writes header information. #ifdef __WINDOWS__ LPCWSTR lpcwFilename = (LPCWSTR)m_fileName.utf16(); //Pointer valid until string changed m_pSndfile = sf_wchar_open( lpcwFilename, SFM_WRITE, &m_sfInfo); #else QByteArray qbaFilename = m_fileName.toUtf8(); m_pSndfile = sf_open(qbaFilename.data(), SFM_WRITE, &m_sfInfo); #endif if (m_pSndfile) { sf_command(m_pSndfile, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ; // Set meta data int ret; ret = sf_set_string(m_pSndfile, SF_STR_TITLE, m_baTitle.data()); if(ret != 0) qDebug("libsndfile: %s", sf_error_number(ret)); ret = sf_set_string(m_pSndfile, SF_STR_ARTIST, m_baAuthor.data()); if(ret != 0) qDebug("libsndfile: %s", sf_error_number(ret)); ret = sf_set_string(m_pSndfile, SF_STR_COMMENT, m_baAlbum.data()); if(ret != 0) qDebug("libsndfile: %s", sf_error_number(ret)); } } else { // We can use a QFile to write compressed audio. if (m_pEncoder) { m_file.setFileName(m_fileName); m_file.open(QIODevice::WriteOnly); if (m_file.handle() != -1) { m_dataStream.setDevice(&m_file); } } else { return false; } } // Check if file is really open. if (!fileOpen()) { ErrorDialogProperties* props = ErrorDialogHandler::instance()->newDialogProperties(); props->setType(DLG_WARNING); props->setTitle(tr("Recording")); props->setText("<html>"+tr("Could not create audio file for recording!") +"<p>"+tr("Ensure there is enough free disk space and you have write permission for the Recordings folder.") +"<p>"+tr("You can change the location of the Recordings folder in Preferences > Recording.") +"</p></html>"); ErrorDialogHandler::instance()->requestErrorDialog(props); return false; } return true; }