FLACSource::FLACSource(const FLACModule &module, const std::shared_ptr<FILE> &fp): m_eof(false), m_giveup(false), m_initialize_done(false), m_length(0), m_position(0), m_fp(fp), m_module(module) { char buffer[33]; util::check_eof(util::nread(fileno(m_fp.get()), buffer, 33) == 33); if (std::memcmp(buffer, "ID3", 3) == 0) { uint32_t size = 0; for (int i = 6; i < 10; ++i) { size <<= 7; size |= buffer[i]; } CHECKCRT(_lseeki64(fileno(m_fp.get()), 10 + size, SEEK_SET) < 0); util::check_eof(util::nread(fileno(m_fp.get()), buffer, 33) == 33); } uint32_t fcc = util::fourcc(buffer); if ((fcc != 'fLaC' && fcc != 'OggS') || (fcc == 'OggS' && std::memcmp(&buffer[28], "\177FLAC", 5))) throw std::runtime_error("Not a FLAC file"); CHECKCRT(_lseeki64(fileno(m_fp.get()), 0, SEEK_SET) < 0); m_decoder = decoder_t(m_module.stream_decoder_new(), std::bind1st(std::mem_fun(&FLACSource::close), this)); TRYFL(m_module.stream_decoder_set_metadata_respond( m_decoder.get(), FLAC__METADATA_TYPE_VORBIS_COMMENT)); TRYFL(m_module.stream_decoder_set_metadata_respond( m_decoder.get(), FLAC__METADATA_TYPE_PICTURE)); TRYFL((fcc == 'OggS' ? m_module.stream_decoder_init_ogg_stream : m_module.stream_decoder_init_stream) (m_decoder.get(), staticReadCallback, staticSeekCallback, staticTellCallback, staticLengthCallback, staticEofCallback, staticWriteCallback, staticMetadataCallback, staticErrorCallback, this) == FLAC__STREAM_DECODER_INIT_STATUS_OK); TRYFL(m_module.stream_decoder_process_until_end_of_metadata( m_decoder.get())); if (m_giveup || m_asbd.mBitsPerChannel == 0) flac::want(false); m_buffer.set_unit(m_asbd.mChannelsPerFrame); m_initialize_done = true; }
PipedReader::PipedReader(std::shared_ptr<ISource> &src): FilterBase(src), m_thread(0), m_position(0) { HANDLE hr, hw; int fd; FILE *fp; uint32_t bpf = src->getSampleFormat().mBytesPerFrame; if (!CreatePipe(&hr, &hw, 0, NSAMPLES * bpf * PIPE_BUF_FACTOR)) win32::throw_error("CreatePipe", GetLastError()); CHECKCRT((fd = _open_osfhandle(reinterpret_cast<intptr_t>(hr), _O_RDONLY|_O_BINARY)) < 0); CHECKCRT((fp = _fdopen(fd, "rb")) == 0); m_readPipe.reset(fp, std::fclose); m_writePipe.reset(hw, CloseHandle); }