#include #include namespace nana{ namespace audio { namespace detail { //class audio_stream bool audio_stream::open(const nana::string& file) { fs_.open(static_cast(nana::charset(file)), std::ios::binary); if(fs_) { wave_spec::master_riff_chunk riff; fs_.read(reinterpret_cast(&riff), sizeof(riff)); if(riff.ckID == *reinterpret_cast("RIFF") && riff.waveID == *reinterpret_cast("WAVE")) { fs_.read(reinterpret_cast(&ck_format_), sizeof(ck_format_)); if(ck_format_.ckID == *reinterpret_cast("fmt ") && ck_format_.wFormatTag == 1) //Only support PCM format { std::size_t cksize = _m_locate_chunck(*reinterpret_cast("data")); if(cksize) { pcm_data_pos_ = static_cast(fs_.tellg()); pcm_data_size_ = cksize; return true; } } } } return false; } void audio_stream::close() { fs_.close(); } bool audio_stream::empty() const { return (!fs_); } const wave_spec::format_chunck & audio_stream::format() const { return ck_format_; } std::size_t audio_stream::data_length() const { return data_size_; } void audio_stream::locate() { fs_.clear(); fs_.seekg(pcm_data_pos_, std::ios::beg); data_size_ = pcm_data_size_; } std::size_t audio_stream::read(void * buf, std::size_t len) { fs_.read(reinterpret_cast(buf), static_cast(len <= data_size_ ? len : data_size_)); std::size_t read_bytes = static_cast(fs_.gcount()); data_size_ -= read_bytes; return read_bytes; } std::size_t audio_stream::_m_locate_chunck(unsigned ckID) { chunck ck; while(true) { fs_.read(reinterpret_cast(&ck), sizeof(ck)); if(fs_.gcount() != sizeof(ck)) break; if(ck.ckID == ckID) return ck.cksize; if(ck.ckID == *reinterpret_cast("data")) fs_.seekg(ck.cksize + (ck.cksize & 1 ? 1 : 0), std::ios::cur); else fs_.seekg(ck.cksize, std::ios::cur); } return 0; } //end class audio_stream }//end namespace detail }//end namespace audio }//end namespace nana