fix an audio_stream issue

occurs when pcmwaveformat's cksize is larger than sizeof pcmwaveformat
This commit is contained in:
Jinhao 2015-07-30 23:26:56 +08:00
parent 8490e05497
commit 8bf35968ef
2 changed files with 24 additions and 22 deletions

View File

@ -12,19 +12,19 @@ namespace nana{ namespace audio{
#pragma pack(1) #pragma pack(1)
struct master_riff_chunk struct master_riff_chunk
{ {
unsigned long ckID; //"RIFF" unsigned ckID; //"RIFF"
unsigned long cksize; unsigned cksize;
unsigned long waveID; //"WAVE" unsigned waveID; //"WAVE"
}; };
struct format_chunck struct format_chunck
{ {
unsigned long ckID; //"fmt " unsigned ckID; //"fmt "
unsigned long cksize; unsigned cksize;
unsigned short wFormatTag; unsigned short wFormatTag;
unsigned short nChannels; unsigned short nChannels;
unsigned long nSamplePerSec; unsigned nSamplePerSec;
unsigned long nAvgBytesPerSec; unsigned nAvgBytesPerSec;
unsigned short nBlockAlign; unsigned short nBlockAlign;
unsigned short wBitsPerSample; unsigned short wBitsPerSample;
}; };
@ -32,19 +32,19 @@ namespace nana{ namespace audio{
#elif defined(NANA_LINUX) #elif defined(NANA_LINUX)
struct master_riff_chunk struct master_riff_chunk
{ {
unsigned long ckID; //"RIFF" unsigned ckID; //"RIFF"
unsigned long cksize; unsigned cksize;
unsigned long waveID; //"WAVE" unsigned waveID; //"WAVE"
}__attribute__((packed)); }__attribute__((packed));
struct format_chunck struct format_chunck
{ {
unsigned long ckID; //"fmt " unsigned ckID; //"fmt "
unsigned long cksize; unsigned cksize;
unsigned short wFormatTag; unsigned short wFormatTag;
unsigned short nChannels; unsigned short nChannels;
unsigned long nSamplePerSec; unsigned nSamplePerSec;
unsigned long nAvgBytesPerSec; unsigned nAvgBytesPerSec;
unsigned short nBlockAlign; unsigned short nBlockAlign;
unsigned short wBitsPerSample; unsigned short wBitsPerSample;
}__attribute__((packed)); }__attribute__((packed));
@ -55,8 +55,8 @@ namespace nana{ namespace audio{
{ {
struct chunck struct chunck
{ {
unsigned long ckID; unsigned ckID;
unsigned long cksize; unsigned cksize;
}; };
public: public:
bool open(const nana::string& file); bool open(const nana::string& file);

View File

@ -8,18 +8,20 @@ namespace nana{ namespace audio
//class audio_stream //class audio_stream
bool audio_stream::open(const nana::string& file) bool audio_stream::open(const nana::string& file)
{ {
std::string fname = nana::charset(file); fs_.open(static_cast<std::string>(charset(file)), std::ios::binary);
fs_.open(fname, std::ios::binary);
if(fs_) if(fs_)
{ {
wave_spec::master_riff_chunk riff; wave_spec::master_riff_chunk riff;
fs_.read(reinterpret_cast<char*>(&riff), sizeof(riff)); fs_.read(reinterpret_cast<char*>(&riff), sizeof(riff));
if(riff.ckID == *reinterpret_cast<const unsigned long*>("RIFF") && riff.waveID == *reinterpret_cast<const unsigned long*>("WAVE")) if(riff.ckID == *reinterpret_cast<const unsigned*>("RIFF") && riff.waveID == *reinterpret_cast<const unsigned*>("WAVE"))
{ {
fs_.read(reinterpret_cast<char*>(&ck_format_), sizeof(ck_format_)); fs_.read(reinterpret_cast<char*>(&ck_format_), sizeof(ck_format_));
if(ck_format_.ckID == *reinterpret_cast<const unsigned long*>("fmt ") && ck_format_.wFormatTag == 1) //Only support PCM format if(ck_format_.ckID == *reinterpret_cast<const unsigned*>("fmt ") && ck_format_.wFormatTag == 1) //Only support PCM format
{ {
std::size_t cksize = _m_locate_chunck(*reinterpret_cast<const unsigned long*>("data")); if (ck_format_.cksize > 16)
fs_.seekg(ck_format_.cksize - 16, std::ios::cur);
std::size_t cksize = _m_locate_chunck(*reinterpret_cast<const unsigned*>("data"));
if(cksize) if(cksize)
{ {
pcm_data_pos_ = static_cast<std::size_t>(fs_.tellg()); pcm_data_pos_ = static_cast<std::size_t>(fs_.tellg());
@ -78,7 +80,7 @@ namespace nana{ namespace audio
if(ck.ckID == ckID) if(ck.ckID == ckID)
return ck.cksize; return ck.cksize;
if(ck.ckID == *reinterpret_cast<const unsigned long*>("data")) if(ck.ckID == *reinterpret_cast<const unsigned*>("data"))
fs_.seekg(ck.cksize + (ck.cksize & 1 ? 1 : 0), std::ios::cur); fs_.seekg(ck.cksize + (ck.cksize & 1 ? 1 : 0), std::ios::cur);
else else
fs_.seekg(ck.cksize, std::ios::cur); fs_.seekg(ck.cksize, std::ios::cur);