Chris@148: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@148: Chris@148: /* Chris@148: Sonic Visualiser Chris@148: An audio file viewer and annotation editor. Chris@148: Centre for Digital Music, Queen Mary, University of London. Chris@148: This file copyright 2006 Chris Cannam. Chris@148: Chris@148: This program is free software; you can redistribute it and/or Chris@148: modify it under the terms of the GNU General Public License as Chris@148: published by the Free Software Foundation; either version 2 of the Chris@148: License, or (at your option) any later version. See the file Chris@148: COPYING included with this distribution for more information. Chris@148: */ Chris@148: Chris@148: #include "WavFileReader.h" Chris@148: Chris@148: #include Chris@148: Chris@148: WavFileReader::WavFileReader(QString path) : Chris@148: m_file(0), Chris@148: m_path(path), Chris@148: m_buffer(0), Chris@148: m_bufsiz(0), Chris@148: m_lastStart(0), Chris@148: m_lastCount(0) Chris@148: { Chris@148: m_frameCount = 0; Chris@148: m_channelCount = 0; Chris@148: m_sampleRate = 0; Chris@148: Chris@148: m_fileInfo.format = 0; Chris@148: m_fileInfo.frames = 0; Chris@148: m_file = sf_open(m_path.toLocal8Bit(), SFM_READ, &m_fileInfo); Chris@148: Chris@148: if (!m_file || m_fileInfo.frames <= 0 || m_fileInfo.channels <= 0) { Chris@148: std::cerr << "WavFileReader::initialize: Failed to open file (" Chris@148: << sf_strerror(m_file) << ")" << std::endl; Chris@148: Chris@148: if (m_file) { Chris@148: m_error = QString("Couldn't load audio file '%1':\n%2") Chris@148: .arg(m_path).arg(sf_strerror(m_file)); Chris@148: } else { Chris@148: m_error = QString("Failed to open audio file '%1'") Chris@148: .arg(m_path); Chris@148: } Chris@148: return; Chris@148: } Chris@148: Chris@148: m_frameCount = m_fileInfo.frames; Chris@148: m_channelCount = m_fileInfo.channels; Chris@148: m_sampleRate = m_fileInfo.samplerate; Chris@148: } Chris@148: Chris@148: WavFileReader::~WavFileReader() Chris@148: { Chris@148: if (m_file) sf_close(m_file); Chris@148: } Chris@148: Chris@148: void Chris@148: WavFileReader::getInterleavedFrames(size_t start, size_t count, Chris@148: SampleBlock &results) const Chris@148: { Chris@148: results.clear(); Chris@148: if (!m_file || !m_channelCount) return; Chris@148: if (count == 0) return; Chris@148: Chris@148: if ((long)start >= m_fileInfo.frames) { Chris@148: return; Chris@148: } Chris@148: Chris@148: if (long(start + count) > m_fileInfo.frames) { Chris@148: count = m_fileInfo.frames - start; Chris@148: } Chris@148: Chris@148: sf_count_t readCount = 0; Chris@148: Chris@148: m_mutex.lock(); Chris@148: Chris@148: if (start != m_lastStart || count != m_lastCount) { Chris@148: Chris@148: if (sf_seek(m_file, start, SEEK_SET) < 0) { Chris@148: m_mutex.unlock(); Chris@148: return; Chris@148: } Chris@148: Chris@148: if (count * m_fileInfo.channels > m_bufsiz) { Chris@148: // std::cerr << "WavFileReader: Reallocating buffer for " << count Chris@148: // << " frames, " << m_fileInfo.channels << " channels: " Chris@148: // << m_bufsiz << " floats" << std::endl; Chris@148: m_bufsiz = count * m_fileInfo.channels; Chris@148: delete[] m_buffer; Chris@148: m_buffer = new float[m_bufsiz]; Chris@148: } Chris@148: Chris@148: if ((readCount = sf_readf_float(m_file, m_buffer, count)) < 0) { Chris@148: m_mutex.unlock(); Chris@148: return; Chris@148: } Chris@148: Chris@148: m_lastStart = start; Chris@148: m_lastCount = readCount; Chris@148: } Chris@148: Chris@148: for (size_t i = 0; i < count * m_fileInfo.channels; ++i) { Chris@148: results.push_back(m_buffer[i]); Chris@148: } Chris@148: Chris@148: m_mutex.unlock(); Chris@148: return; Chris@148: } Chris@148: