annotate data/fileio/WavFileReader.cpp @ 282:d9319859a4cf tip

(none)
author benoitrigolleau
date Fri, 31 Oct 2008 11:00:24 +0000
parents fc9323a41f5a
children
rev   line source
lbajardsilogic@0 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
lbajardsilogic@0 2
lbajardsilogic@0 3 /*
lbajardsilogic@0 4 Sonic Visualiser
lbajardsilogic@0 5 An audio file viewer and annotation editor.
lbajardsilogic@0 6 Centre for Digital Music, Queen Mary, University of London.
lbajardsilogic@0 7 This file copyright 2006 Chris Cannam and QMUL.
lbajardsilogic@0 8
lbajardsilogic@0 9 This program is free software; you can redistribute it and/or
lbajardsilogic@0 10 modify it under the terms of the GNU General Public License as
lbajardsilogic@0 11 published by the Free Software Foundation; either version 2 of the
lbajardsilogic@0 12 License, or (at your option) any later version. See the file
lbajardsilogic@0 13 COPYING included with this distribution for more information.
lbajardsilogic@0 14 */
lbajardsilogic@0 15
lbajardsilogic@0 16 #include "WavFileReader.h"
lbajardsilogic@0 17
lbajardsilogic@0 18 #include <iostream>
lbajardsilogic@0 19
lbajardsilogic@0 20 #include <QMutexLocker>
lbajardsilogic@0 21
lbajardsilogic@0 22 WavFileReader::WavFileReader(QString path, bool fileUpdating) :
lbajardsilogic@0 23 m_file(0),
lbajardsilogic@0 24 m_path(path),
lbajardsilogic@0 25 m_buffer(0),
lbajardsilogic@0 26 m_bufsiz(0),
lbajardsilogic@0 27 m_lastStart(0),
lbajardsilogic@0 28 m_lastCount(0),
lbajardsilogic@0 29 m_updating(fileUpdating)
lbajardsilogic@0 30 {
lbajardsilogic@0 31 m_frameCount = 0;
lbajardsilogic@0 32 m_channelCount = 0;
lbajardsilogic@0 33 m_sampleRate = 0;
lbajardsilogic@0 34
lbajardsilogic@0 35 m_fileInfo.format = 0;
lbajardsilogic@0 36 m_fileInfo.frames = 0;
lbajardsilogic@0 37 m_file = sf_open(m_path.toLocal8Bit(), SFM_READ, &m_fileInfo);
lbajardsilogic@0 38
lbajardsilogic@0 39 if (!m_file || (!fileUpdating && m_fileInfo.channels <= 0)) {
lbajardsilogic@0 40 std::cerr << "WavFileReader::initialize: Failed to open file ("
lbajardsilogic@0 41 << sf_strerror(m_file) << ")" << std::endl;
lbajardsilogic@0 42
lbajardsilogic@0 43 if (m_file) {
lbajardsilogic@0 44 m_error = QString("Couldn't load audio file '%1':\n%2")
lbajardsilogic@0 45 .arg(m_path).arg(sf_strerror(m_file));
lbajardsilogic@0 46 } else {
lbajardsilogic@0 47 m_error = QString("Failed to open audio file '%1'")
lbajardsilogic@0 48 .arg(m_path);
lbajardsilogic@0 49 }
lbajardsilogic@0 50 return;
lbajardsilogic@0 51 }
lbajardsilogic@0 52
lbajardsilogic@0 53 if (m_fileInfo.channels > 0) {
lbajardsilogic@0 54 m_frameCount = m_fileInfo.frames;
lbajardsilogic@0 55 m_channelCount = m_fileInfo.channels;
lbajardsilogic@0 56 m_sampleRate = m_fileInfo.samplerate;
lbajardsilogic@0 57 }
lbajardsilogic@0 58
lbajardsilogic@0 59 // std::cerr << "WavFileReader: Frame count " << m_frameCount << ", channel count " << m_channelCount << ", sample rate " << m_sampleRate << std::endl;
lbajardsilogic@0 60
lbajardsilogic@0 61 }
lbajardsilogic@0 62
lbajardsilogic@0 63 WavFileReader::~WavFileReader()
lbajardsilogic@0 64 {
lbajardsilogic@0 65 if (m_file) sf_close(m_file);
lbajardsilogic@0 66 }
lbajardsilogic@0 67
lbajardsilogic@0 68 void
lbajardsilogic@0 69 WavFileReader::updateFrameCount()
lbajardsilogic@0 70 {
lbajardsilogic@0 71 QMutexLocker locker(&m_mutex);
lbajardsilogic@0 72
lbajardsilogic@0 73 size_t prevCount = m_fileInfo.frames;
lbajardsilogic@0 74
lbajardsilogic@0 75 if (m_file) {
lbajardsilogic@0 76 sf_close(m_file);
lbajardsilogic@0 77 m_file = sf_open(m_path.toLocal8Bit(), SFM_READ, &m_fileInfo);
lbajardsilogic@0 78 if (!m_file || m_fileInfo.channels <= 0) {
lbajardsilogic@0 79 std::cerr << "WavFileReader::updateFrameCount: Failed to open file ("
lbajardsilogic@0 80 << sf_strerror(m_file) << ")" << std::endl;
lbajardsilogic@0 81 }
lbajardsilogic@0 82 }
lbajardsilogic@0 83
lbajardsilogic@0 84 // std::cerr << "WavFileReader::updateFrameCount: now " << m_fileInfo.frames << std::endl;
lbajardsilogic@0 85
lbajardsilogic@0 86 m_frameCount = m_fileInfo.frames;
lbajardsilogic@0 87
lbajardsilogic@0 88 if (m_channelCount == 0) {
lbajardsilogic@0 89 m_channelCount = m_fileInfo.channels;
lbajardsilogic@0 90 m_sampleRate = m_fileInfo.samplerate;
lbajardsilogic@0 91 }
lbajardsilogic@0 92
lbajardsilogic@0 93 if (m_frameCount != prevCount) {
lbajardsilogic@0 94 // std::cerr << "frameCountChanged" << std::endl;
lbajardsilogic@0 95 emit frameCountChanged();
lbajardsilogic@0 96 }
lbajardsilogic@0 97 }
lbajardsilogic@0 98
lbajardsilogic@0 99 void
lbajardsilogic@0 100 WavFileReader::updateDone()
lbajardsilogic@0 101 {
lbajardsilogic@0 102 updateFrameCount();
lbajardsilogic@0 103 m_updating = false;
lbajardsilogic@0 104 }
lbajardsilogic@0 105
lbajardsilogic@0 106 void
lbajardsilogic@0 107 WavFileReader::getInterleavedFrames(size_t start, size_t count,
lbajardsilogic@0 108 SampleBlock &results) const
lbajardsilogic@0 109 {
lbajardsilogic@0 110 if (count == 0) return;
lbajardsilogic@0 111 results.clear();
lbajardsilogic@0 112
lbajardsilogic@0 113 QMutexLocker locker(&m_mutex);
lbajardsilogic@0 114
lbajardsilogic@0 115 if (!m_file || !m_channelCount) {
lbajardsilogic@0 116 return;
lbajardsilogic@0 117 }
lbajardsilogic@0 118
lbajardsilogic@0 119 if ((long)start >= m_fileInfo.frames) {
lbajardsilogic@0 120 // std::cerr << "WavFileReader::getInterleavedFrames: " << start
lbajardsilogic@0 121 // << " > " << m_fileInfo.frames << std::endl;
lbajardsilogic@0 122 return;
lbajardsilogic@0 123 }
lbajardsilogic@0 124
lbajardsilogic@0 125 if (long(start + count) > m_fileInfo.frames) {
lbajardsilogic@0 126 count = m_fileInfo.frames - start;
lbajardsilogic@0 127 }
lbajardsilogic@0 128
lbajardsilogic@0 129 sf_count_t readCount = 0;
lbajardsilogic@0 130
lbajardsilogic@0 131 if (start != m_lastStart || count != m_lastCount) {
lbajardsilogic@0 132
lbajardsilogic@0 133 if (sf_seek(m_file, start, SEEK_SET) < 0) {
lbajardsilogic@0 134 // std::cerr << "sf_seek failed" << std::endl;
lbajardsilogic@0 135 return;
lbajardsilogic@0 136 }
lbajardsilogic@0 137
lbajardsilogic@0 138 if (count * m_fileInfo.channels > m_bufsiz) {
lbajardsilogic@0 139 // std::cerr << "WavFileReader: Reallocating buffer for " << count
lbajardsilogic@0 140 // << " frames, " << m_fileInfo.channels << " channels: "
lbajardsilogic@0 141 // << m_bufsiz << " floats" << std::endl;
lbajardsilogic@0 142 m_bufsiz = count * m_fileInfo.channels;
lbajardsilogic@0 143 delete[] m_buffer;
lbajardsilogic@0 144 m_buffer = new float[m_bufsiz];
lbajardsilogic@0 145 }
lbajardsilogic@0 146
lbajardsilogic@0 147 if ((readCount = sf_readf_float(m_file, m_buffer, count)) < 0) {
lbajardsilogic@0 148 // std::cerr << "sf_readf_float failed" << std::endl;
lbajardsilogic@0 149 return;
lbajardsilogic@0 150 }
lbajardsilogic@0 151
lbajardsilogic@0 152 m_lastStart = start;
lbajardsilogic@0 153 m_lastCount = readCount;
lbajardsilogic@0 154 }
lbajardsilogic@0 155
lbajardsilogic@0 156 for (size_t i = 0; i < count * m_fileInfo.channels; ++i) {
lbajardsilogic@0 157 if (i >= m_bufsiz) {
lbajardsilogic@0 158 std::cerr << "INTERNAL ERROR: WavFileReader::getInterleavedFrames: " << i << " >= " << m_bufsiz << std::endl;
lbajardsilogic@0 159 }
lbajardsilogic@0 160 results.push_back(m_buffer[i]);
lbajardsilogic@0 161 }
lbajardsilogic@0 162
lbajardsilogic@0 163 return;
lbajardsilogic@0 164 }
lbajardsilogic@0 165
lbajardsilogic@0 166 void
lbajardsilogic@0 167 WavFileReader::getSupportedExtensions(std::set<QString> &extensions)
lbajardsilogic@0 168 {
lbajardsilogic@0 169 int count;
lbajardsilogic@0 170
lbajardsilogic@0 171 if (sf_command(0, SFC_GET_FORMAT_MAJOR_COUNT, &count, sizeof(count))) {
lbajardsilogic@0 172 extensions.insert("wav");
lbajardsilogic@0 173 extensions.insert("aiff");
lbajardsilogic@0 174 extensions.insert("aif");
lbajardsilogic@0 175 return;
lbajardsilogic@0 176 }
lbajardsilogic@0 177
lbajardsilogic@0 178 SF_FORMAT_INFO info;
lbajardsilogic@0 179 for (int i = 0; i < count; ++i) {
lbajardsilogic@0 180 info.format = i;
lbajardsilogic@0 181 if (!sf_command(0, SFC_GET_FORMAT_MAJOR, &info, sizeof(info))) {
lbajardsilogic@0 182 extensions.insert(info.extension);
lbajardsilogic@0 183 }
lbajardsilogic@0 184 }
lbajardsilogic@0 185 }