C++ 使用portaudio和sndfile播放wav文件
我已经编写了一个使用portaudio和sndfile播放声音文件的函数。不幸的是,音质很差。声音更像是嘶嘶声。下面是我正在使用的函数的源代码C++ 使用portaudio和sndfile播放wav文件,c++,portaudio,libsndfile,C++,Portaudio,Libsndfile,我已经编写了一个使用portaudio和sndfile播放声音文件的函数。不幸的是,音质很差。声音更像是嘶嘶声。下面是我正在使用的函数的源代码 #define _GLIBCXX_USE_C99_MATH 1 #include "PlaySound_config.h" #include <boost/predef.h> #if !defined(USE_PORTAUDIO) // { # define USE_PORTAUDIO 0 # if (! BOOST_OS_CYGWIN
#define _GLIBCXX_USE_C99_MATH 1
#include "PlaySound_config.h"
#include <boost/predef.h>
#if !defined(USE_PORTAUDIO) // {
# define USE_PORTAUDIO 0
# if (! BOOST_OS_CYGWIN && ! BOOST_OS_WINDOWS) // {
# undef USE_PORTAUDIO
# define USE_PORTAUDIO 1
# endif // }
#endif // }
#if (PLAY_SOUND_HAVE_PORTAUDIO_H && PLAY_SOUND_HAVE_SNDFILE_H && PLAY_SOUND_HAVE_SNDFILE_HH && USE_PORTAUDIO) // {
#if (PLAY_SOUND_HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <portaudio.h>
#include <sndfile.hh>
#include <cmath>
#include <fstream>
#include <iostream>
#include <vector>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/format.hpp>
#include "PlaySound.h"
#include "PlaySoundStrings.h"
void SoundWarning(const std::string& message)
{
std::cerr << message << std::endl;
}
bool PlaySoundFile(const std::string& soundFile, unsigned long /* volume */)
{
const int MAX_CHANNELS = 1;
const double SAMPLE_RATE = 11025.0;
const unsigned long FRAMES_PER_BUFFER = 1024;
const size_t BUFFER_LEN = 1024;
using boost::format;
using boost::io::group;
std::string message;
if (soundFile.empty())
{
errno = EINVAL;
message = playSoundStrings[error_invalid_argument];
SoundWarning(message);
return false;
}
boost::filesystem::path soundFilePath(soundFile);
if (! boost::filesystem::exists(soundFilePath))
{
errno = EINVAL;
message = str(format(playSoundStrings[error_file_does_not_exist]) % soundFile.c_str());
SoundWarning(message);
return false;
}
PaError paError = Pa_Initialize();
if (paError != paNoError)
{
message = str(format(playSoundStrings[error_pa_initialize_failed]) % Pa_GetErrorText(paError));
SoundWarning(message);
return false;
}
SNDFILE* sndFile;
SF_INFO sfInfo;
sndFile = sf_open(soundFile.c_str(), SFM_READ, &sfInfo);
if (! sndFile)
{
message = str(format(playSoundStrings[error_sf_open_failed]) % soundFile.c_str() % sf_strerror(nullptr));
SoundWarning(message);
Pa_Terminate();
return false;
}
if (sfInfo.channels > MAX_CHANNELS)
{
message = str(format(playSoundStrings[error_too_many_channels]) % sfInfo.channels % MAX_CHANNELS);
SoundWarning(message);
Pa_Terminate();
return false;
}
PaStream* stream = nullptr;
PaStreamParameters paStreamParameters;
paStreamParameters.device = Pa_GetDefaultOutputDevice();
paStreamParameters.channelCount = sfInfo.channels;
paStreamParameters.sampleFormat = paInt16;
paStreamParameters.suggestedLatency = Pa_GetDeviceInfo(paStreamParameters.device)->defaultLowOutputLatency;
paStreamParameters.hostApiSpecificStreamInfo = nullptr;
paError = Pa_OpenStream(
&stream, nullptr, &paStreamParameters,
SAMPLE_RATE, FRAMES_PER_BUFFER, paClipOff,
nullptr, nullptr);
if (paError != paNoError || ! stream)
{
message = str(format(playSoundStrings[error_pa_open_stream_failed]) % Pa_GetErrorText(paError));
SoundWarning(message);
Pa_Terminate();
return false;
}
paError = Pa_StartStream(stream);
if (paError != paNoError)
{
message = str(format(playSoundStrings[error_pa_start_stream_failed]) % Pa_GetErrorText(paError));
SoundWarning(message);
Pa_Terminate();
return false;
}
sf_count_t readCount = 0;
double data[BUFFER_LEN];
while ((readCount = sf_read_double(sndFile, data, BUFFER_LEN)))
{
paError = Pa_WriteStream(stream, data, BUFFER_LEN);
if (paError != paNoError)
{
message = str(format(playSoundStrings[error_pa_write_stream_failed]) % Pa_GetErrorText(paError));
SoundWarning(message);
break;
}
}
paError = Pa_CloseStream(stream);
if (paError != paNoError)
{
message = str(format(playSoundStrings[error_pa_close_stream_failed]) % Pa_GetErrorText(paError));
SoundWarning(message);
Pa_Terminate();
return false;
}
Pa_Terminate();
return true;
}
\define\u GLIBCXX\u USE\u C99\u MATH 1
#包括“PlaySound_config.h”
#包括
#如果!已定义(使用端口)//{
#定义使用端口0
#如果(!BOOST_OS_CYGWIN&!BOOST_OS_WINDOWS)//{
#未定义的使用
#定义使用端口1
#endif/}
#endif/}
#如果(播放声音、播放声音、播放文件、播放声音、播放文件、播放声音、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、使用文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件{
#如果(播放声音,播放声音)
#包括
#恩迪夫
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括“PlaySound.h”
#包括“PlaySoundStrings.h”
void SoundWarning(const std::string和message)
{
标准:cerr defaultLowOutputLatency;
paStreamParameters.hostApiSpecificStreamInfo=nullptr;
paError=Pa_OpenStream(
&流、nullptr和Pastream参数,
采样率、每缓冲区帧数、paClipOff、,
nullptr,nullptr);
如果(paError!=paNoError | |!流)
{
message=str(格式(playSoundStrings[错误\u pa\u打开\u流\u失败])%pa\u GetErrorText(paError));
声音警告(信息);
Pa_Terminate();
返回false;
}
paError=Pa_StartStream(溪流);
如果(paError!=paNoError)
{
message=str(格式(playSoundStrings[错误\u pa\u开始\u流\u失败])%pa\u GetErrorText(paError));
声音警告(信息);
Pa_Terminate();
返回false;
}
sf_count_t readCount=0;
双数据[BUFFER_LEN];
而((readCount=sf\u read\u double(sndFile、data、BUFFER\u LEN)))
{
paError=Pa_WriteStream(流、数据、缓冲区长度);
如果(paError!=paNoError)
{
message=str(格式(playSoundStrings[错误\u pa\u写入\u流\u失败])%pa\u GetErrorText(paError));
声音警告(信息);
打破
}
}
paError=Pa_CloseStream(溪流);
如果(paError!=paNoError)
{
message=str(格式(playSoundStrings[错误\u pa\u关闭\u流\u失败])%pa\u GetErrorText(paError));
声音警告(信息);
Pa_Terminate();
返回false;
}
Pa_Terminate();
返回true;
}
我在文章中看到了一些示例代码,但示例不完整。它似乎只会播放文件的前五秒钟。我想播放整个文件
知道我做错了什么吗
这段代码是我项目的一部分。我在代码的原始版本中犯了几个错误。第一个错误是在初始化PaStreamParameters结构的sampleFormat成员的行中 在我的原始代码中,我初始化了这个成员,如下所示
paStreamParameters.sampleFormat = paInt16;
paStreamParameters.sampleFormat = paInt32;
#define _GLIBCXX_USE_C99_MATH 1
#include "PlaySound_config.h"
#include <boost/predef.h>
#if !defined(USE_PORTAUDIO) // {
# define USE_PORTAUDIO 0
# if (! BOOST_OS_CYGWIN && ! BOOST_OS_WINDOWS) // {
# undef USE_PORTAUDIO
# define USE_PORTAUDIO 1
# endif // }
#endif // }
#if (PLAY_SOUND_HAVE_PORTAUDIO_H && PLAY_SOUND_HAVE_SNDFILE_H && PLAY_SOUND_HAVE_SNDFILE_HH && USE_PORTAUDIO) // {
#if (PLAY_SOUND_HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <portaudio.h>
#include <sndfile.hh>
#include <cmath>
#include <fstream>
#include <iostream>
#include <vector>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/format.hpp>
#include "PlaySound.h"
#include "PlaySoundStrings.h"
void SoundWarning(const std::string& message)
{
std::cerr << message << std::endl;
}
bool PlaySoundFile(const std::string& soundFile, unsigned long /* volume */)
{
const int MAX_CHANNELS = 1;
const size_t BUFFER_LEN = 1024;
using boost::format;
using boost::io::group;
std::string message;
if (soundFile.empty())
{
errno = EINVAL;
message = playSoundStrings[error_invalid_argument];
SoundWarning(message);
return false;
}
boost::filesystem::path soundFilePath(soundFile);
if (! boost::filesystem::exists(soundFilePath))
{
errno = EINVAL;
message = str(format(playSoundStrings[error_file_does_not_exist]) % soundFile.c_str());
SoundWarning(message);
return false;
}
PaError paError = Pa_Initialize();
if (paError != paNoError)
{
message = str(format(playSoundStrings[error_pa_initialize_failed]) % Pa_GetErrorText(paError));
SoundWarning(message);
return false;
}
SNDFILE* sndFile = nullptr;
SF_INFO sfInfo;
::memset(&sfInfo, 0, sizeof(sfInfo));
sndFile = sf_open(soundFile.c_str(), SFM_READ, &sfInfo);
if (! sndFile)
{
message = str(format(playSoundStrings[error_sf_open_failed]) % soundFile.c_str() % sf_strerror(nullptr));
SoundWarning(message);
Pa_Terminate();
return false;
}
if (sfInfo.channels > MAX_CHANNELS)
{
message = str(format(playSoundStrings[error_too_many_channels]) % sfInfo.channels % MAX_CHANNELS);
SoundWarning(message);
Pa_Terminate();
return false;
}
PaStream* stream = nullptr;
PaStreamParameters paStreamParameters;
paStreamParameters.device = Pa_GetDefaultOutputDevice();
paStreamParameters.channelCount = sfInfo.channels;
paStreamParameters.sampleFormat = paInt32;
paStreamParameters.suggestedLatency = Pa_GetDeviceInfo(paStreamParameters.device)->defaultLowOutputLatency;
paStreamParameters.hostApiSpecificStreamInfo = nullptr;
paError = Pa_OpenStream(
&stream, nullptr, &paStreamParameters,
sfInfo.samplerate, paFramesPerBufferUnspecified, paClipOff,
nullptr, nullptr);
if (paError != paNoError || ! stream)
{
message = str(format(playSoundStrings[error_pa_open_stream_failed]) % Pa_GetErrorText(paError));
SoundWarning(message);
Pa_Terminate();
return false;
}
paError = Pa_StartStream(stream);
if (paError != paNoError)
{
message = str(format(playSoundStrings[error_pa_start_stream_failed]) % Pa_GetErrorText(paError));
SoundWarning(message);
Pa_Terminate();
return false;
}
int subFormat = sfInfo.format & SF_FORMAT_SUBMASK;
double scale = 1.0;
if (subFormat == SF_FORMAT_FLOAT || subFormat == SF_FORMAT_DOUBLE)
{
sf_command(sndFile, SFC_CALC_SIGNAL_MAX, &scale, sizeof(scale));
if (scale < 1e-10)
{
scale = 1.0;
}
else
{
scale = 32700.0 / scale;
}
}
sf_count_t readCount = 0;
float data[BUFFER_LEN];
::memset(data, 0, sizeof(data));
while ((readCount = sf_read_float(sndFile, data, BUFFER_LEN)))
{
if (subFormat == SF_FORMAT_FLOAT || subFormat == SF_FORMAT_DOUBLE)
{
int m = 0;
for (m = 0 ; m < readCount ; ++m)
{
data[m] *= scale;
}
}
paError = Pa_WriteStream(stream, data, BUFFER_LEN);
if (paError != paNoError)
{
message = str(format(playSoundStrings[error_pa_write_stream_failed]) % Pa_GetErrorText(paError));
SoundWarning(message);
break;
}
::memset(data, 0, sizeof(data));
}
paError = Pa_CloseStream(stream);
if (paError != paNoError)
{
message = str(format(playSoundStrings[error_pa_close_stream_failed]) % Pa_GetErrorText(paError));
SoundWarning(message);
Pa_Terminate();
return false;
}
Pa_Terminate();
return true;
}
我应该按如下方式初始化它
paStreamParameters.sampleFormat = paInt16;
paStreamParameters.sampleFormat = paInt32;
#define _GLIBCXX_USE_C99_MATH 1
#include "PlaySound_config.h"
#include <boost/predef.h>
#if !defined(USE_PORTAUDIO) // {
# define USE_PORTAUDIO 0
# if (! BOOST_OS_CYGWIN && ! BOOST_OS_WINDOWS) // {
# undef USE_PORTAUDIO
# define USE_PORTAUDIO 1
# endif // }
#endif // }
#if (PLAY_SOUND_HAVE_PORTAUDIO_H && PLAY_SOUND_HAVE_SNDFILE_H && PLAY_SOUND_HAVE_SNDFILE_HH && USE_PORTAUDIO) // {
#if (PLAY_SOUND_HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <portaudio.h>
#include <sndfile.hh>
#include <cmath>
#include <fstream>
#include <iostream>
#include <vector>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/format.hpp>
#include "PlaySound.h"
#include "PlaySoundStrings.h"
void SoundWarning(const std::string& message)
{
std::cerr << message << std::endl;
}
bool PlaySoundFile(const std::string& soundFile, unsigned long /* volume */)
{
const int MAX_CHANNELS = 1;
const size_t BUFFER_LEN = 1024;
using boost::format;
using boost::io::group;
std::string message;
if (soundFile.empty())
{
errno = EINVAL;
message = playSoundStrings[error_invalid_argument];
SoundWarning(message);
return false;
}
boost::filesystem::path soundFilePath(soundFile);
if (! boost::filesystem::exists(soundFilePath))
{
errno = EINVAL;
message = str(format(playSoundStrings[error_file_does_not_exist]) % soundFile.c_str());
SoundWarning(message);
return false;
}
PaError paError = Pa_Initialize();
if (paError != paNoError)
{
message = str(format(playSoundStrings[error_pa_initialize_failed]) % Pa_GetErrorText(paError));
SoundWarning(message);
return false;
}
SNDFILE* sndFile = nullptr;
SF_INFO sfInfo;
::memset(&sfInfo, 0, sizeof(sfInfo));
sndFile = sf_open(soundFile.c_str(), SFM_READ, &sfInfo);
if (! sndFile)
{
message = str(format(playSoundStrings[error_sf_open_failed]) % soundFile.c_str() % sf_strerror(nullptr));
SoundWarning(message);
Pa_Terminate();
return false;
}
if (sfInfo.channels > MAX_CHANNELS)
{
message = str(format(playSoundStrings[error_too_many_channels]) % sfInfo.channels % MAX_CHANNELS);
SoundWarning(message);
Pa_Terminate();
return false;
}
PaStream* stream = nullptr;
PaStreamParameters paStreamParameters;
paStreamParameters.device = Pa_GetDefaultOutputDevice();
paStreamParameters.channelCount = sfInfo.channels;
paStreamParameters.sampleFormat = paInt32;
paStreamParameters.suggestedLatency = Pa_GetDeviceInfo(paStreamParameters.device)->defaultLowOutputLatency;
paStreamParameters.hostApiSpecificStreamInfo = nullptr;
paError = Pa_OpenStream(
&stream, nullptr, &paStreamParameters,
sfInfo.samplerate, paFramesPerBufferUnspecified, paClipOff,
nullptr, nullptr);
if (paError != paNoError || ! stream)
{
message = str(format(playSoundStrings[error_pa_open_stream_failed]) % Pa_GetErrorText(paError));
SoundWarning(message);
Pa_Terminate();
return false;
}
paError = Pa_StartStream(stream);
if (paError != paNoError)
{
message = str(format(playSoundStrings[error_pa_start_stream_failed]) % Pa_GetErrorText(paError));
SoundWarning(message);
Pa_Terminate();
return false;
}
int subFormat = sfInfo.format & SF_FORMAT_SUBMASK;
double scale = 1.0;
if (subFormat == SF_FORMAT_FLOAT || subFormat == SF_FORMAT_DOUBLE)
{
sf_command(sndFile, SFC_CALC_SIGNAL_MAX, &scale, sizeof(scale));
if (scale < 1e-10)
{
scale = 1.0;
}
else
{
scale = 32700.0 / scale;
}
}
sf_count_t readCount = 0;
float data[BUFFER_LEN];
::memset(data, 0, sizeof(data));
while ((readCount = sf_read_float(sndFile, data, BUFFER_LEN)))
{
if (subFormat == SF_FORMAT_FLOAT || subFormat == SF_FORMAT_DOUBLE)
{
int m = 0;
for (m = 0 ; m < readCount ; ++m)
{
data[m] *= scale;
}
}
paError = Pa_WriteStream(stream, data, BUFFER_LEN);
if (paError != paNoError)
{
message = str(format(playSoundStrings[error_pa_write_stream_failed]) % Pa_GetErrorText(paError));
SoundWarning(message);
break;
}
::memset(data, 0, sizeof(data));
}
paError = Pa_CloseStream(stream);
if (paError != paNoError)
{
message = str(format(playSoundStrings[error_pa_close_stream_failed]) % Pa_GetErrorText(paError));
SoundWarning(message);
Pa_Terminate();
return false;
}
Pa_Terminate();
return true;
}
我的下一个错误是调用Pa_OpenStream函数。我将sampleRate参数设置为硬编码常量,在本例中为11025.0。我应该将其设置为SF_INFO结构的sampleRate成员的值
我的第三个错误是使用sf_read_double函数读取声音文件。在我最终发现的几个工作示例中,包括sndfile play应用程序,使用了sf_read_float函数
我的第四个错误是,在将声音文件传递给Pa_WriteStream函数之前,我没有缩放从声音文件读取的数据。我在sndfile play应用程序的源代码中找到了缩放数据的代码
对于任何感兴趣的人,我的源代码的最终版本如下
paStreamParameters.sampleFormat = paInt16;
paStreamParameters.sampleFormat = paInt32;
#define _GLIBCXX_USE_C99_MATH 1
#include "PlaySound_config.h"
#include <boost/predef.h>
#if !defined(USE_PORTAUDIO) // {
# define USE_PORTAUDIO 0
# if (! BOOST_OS_CYGWIN && ! BOOST_OS_WINDOWS) // {
# undef USE_PORTAUDIO
# define USE_PORTAUDIO 1
# endif // }
#endif // }
#if (PLAY_SOUND_HAVE_PORTAUDIO_H && PLAY_SOUND_HAVE_SNDFILE_H && PLAY_SOUND_HAVE_SNDFILE_HH && USE_PORTAUDIO) // {
#if (PLAY_SOUND_HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <portaudio.h>
#include <sndfile.hh>
#include <cmath>
#include <fstream>
#include <iostream>
#include <vector>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/format.hpp>
#include "PlaySound.h"
#include "PlaySoundStrings.h"
void SoundWarning(const std::string& message)
{
std::cerr << message << std::endl;
}
bool PlaySoundFile(const std::string& soundFile, unsigned long /* volume */)
{
const int MAX_CHANNELS = 1;
const size_t BUFFER_LEN = 1024;
using boost::format;
using boost::io::group;
std::string message;
if (soundFile.empty())
{
errno = EINVAL;
message = playSoundStrings[error_invalid_argument];
SoundWarning(message);
return false;
}
boost::filesystem::path soundFilePath(soundFile);
if (! boost::filesystem::exists(soundFilePath))
{
errno = EINVAL;
message = str(format(playSoundStrings[error_file_does_not_exist]) % soundFile.c_str());
SoundWarning(message);
return false;
}
PaError paError = Pa_Initialize();
if (paError != paNoError)
{
message = str(format(playSoundStrings[error_pa_initialize_failed]) % Pa_GetErrorText(paError));
SoundWarning(message);
return false;
}
SNDFILE* sndFile = nullptr;
SF_INFO sfInfo;
::memset(&sfInfo, 0, sizeof(sfInfo));
sndFile = sf_open(soundFile.c_str(), SFM_READ, &sfInfo);
if (! sndFile)
{
message = str(format(playSoundStrings[error_sf_open_failed]) % soundFile.c_str() % sf_strerror(nullptr));
SoundWarning(message);
Pa_Terminate();
return false;
}
if (sfInfo.channels > MAX_CHANNELS)
{
message = str(format(playSoundStrings[error_too_many_channels]) % sfInfo.channels % MAX_CHANNELS);
SoundWarning(message);
Pa_Terminate();
return false;
}
PaStream* stream = nullptr;
PaStreamParameters paStreamParameters;
paStreamParameters.device = Pa_GetDefaultOutputDevice();
paStreamParameters.channelCount = sfInfo.channels;
paStreamParameters.sampleFormat = paInt32;
paStreamParameters.suggestedLatency = Pa_GetDeviceInfo(paStreamParameters.device)->defaultLowOutputLatency;
paStreamParameters.hostApiSpecificStreamInfo = nullptr;
paError = Pa_OpenStream(
&stream, nullptr, &paStreamParameters,
sfInfo.samplerate, paFramesPerBufferUnspecified, paClipOff,
nullptr, nullptr);
if (paError != paNoError || ! stream)
{
message = str(format(playSoundStrings[error_pa_open_stream_failed]) % Pa_GetErrorText(paError));
SoundWarning(message);
Pa_Terminate();
return false;
}
paError = Pa_StartStream(stream);
if (paError != paNoError)
{
message = str(format(playSoundStrings[error_pa_start_stream_failed]) % Pa_GetErrorText(paError));
SoundWarning(message);
Pa_Terminate();
return false;
}
int subFormat = sfInfo.format & SF_FORMAT_SUBMASK;
double scale = 1.0;
if (subFormat == SF_FORMAT_FLOAT || subFormat == SF_FORMAT_DOUBLE)
{
sf_command(sndFile, SFC_CALC_SIGNAL_MAX, &scale, sizeof(scale));
if (scale < 1e-10)
{
scale = 1.0;
}
else
{
scale = 32700.0 / scale;
}
}
sf_count_t readCount = 0;
float data[BUFFER_LEN];
::memset(data, 0, sizeof(data));
while ((readCount = sf_read_float(sndFile, data, BUFFER_LEN)))
{
if (subFormat == SF_FORMAT_FLOAT || subFormat == SF_FORMAT_DOUBLE)
{
int m = 0;
for (m = 0 ; m < readCount ; ++m)
{
data[m] *= scale;
}
}
paError = Pa_WriteStream(stream, data, BUFFER_LEN);
if (paError != paNoError)
{
message = str(format(playSoundStrings[error_pa_write_stream_failed]) % Pa_GetErrorText(paError));
SoundWarning(message);
break;
}
::memset(data, 0, sizeof(data));
}
paError = Pa_CloseStream(stream);
if (paError != paNoError)
{
message = str(format(playSoundStrings[error_pa_close_stream_failed]) % Pa_GetErrorText(paError));
SoundWarning(message);
Pa_Terminate();
return false;
}
Pa_Terminate();
return true;
}
\define\u GLIBCXX\u USE\u C99\u MATH 1
#包括“PlaySound_config.h”
#包括
#如果!已定义(使用_PORTAUDIO)//{
#定义使用端口0
#如果(!BOOST_OS_CYGWIN&!BOOST_OS_WINDOWS)//{
#未定义的使用
#定义使用端口1
#endif/}
#endif/}
#如果(播放声音、播放声音、播放文件、播放声音、播放文件、播放声音、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、使用文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件、播放文件{
#如果(播放声音,播放声音)
#包括
#恩迪夫
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括“PlaySound.h”
#包括“PlaySoundStrings.h”
void SoundWarning(const std::string和message)
{
标准:cerr defaultLowOutputLatency;
paStreamParameters.hostApiSpecificStreamInfo=nullptr;
paError=Pa_OpenStream(
&流、nullptr和Pastream参数,
sfInfo.samplerate,paFramesPerBufferUnspecified,paClipOff,
nullptr,nullptr);
如果(paError!=paNoError | |!流)
{
message=str(格式(playSoundStrings[错误\u pa\u打开\u流\u失败])%pa\u GetErrorText(paError));
声音警告(信息);
Pa_Terminate();
返回false;
}
paError=Pa_StartStream(溪流);
如果(paError!=paNoError)
{
message=str(格式(playSoundStrings[错误\u pa\u开始\u流\u失败])%pa\u GetErrorText(paError));
声音警告(信息);
Pa_Terminate();
返回false;
}
int subFormat=sfInfo.format&SF_format_SUBMASK;
双刻度=1.0;
如果(子格式==SF|U格式|浮点数|子格式==SF|U格式|双精度)
{
sf_命令(sndFile、SFC_CALC_SIGNAL_MAX和scale、sizeof(scale));
如果(刻度<1e-10)
{
比例=1.0;
}
其他的
{
刻度=32700.0/刻度;
}
}
sf_count_t readCount=0;
浮点数据[缓冲区长度];
::memset(数据,0,sizeof(数据));
而((readCount=sf\u read\u float(sndFile、data、BUFFER\u LEN)))
{
如果(子格式==SF|U格式|浮点数|子格式==SF|U格式|双精度)
{
int m=0;
对于(m=0;m