annotate data/fileio/WavFileReader.cpp @ 167:665342c6ec57

* Add a bit of resistance to pane dragging so as to make it harder to inadvertently drag in the other axis from the one you intended
author Chris Cannam
date Fri, 22 Sep 2006 16:46:10 +0000
parents c03ec31005e1
children b0f4555b625e
rev   line source
Chris@148 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@148 2
Chris@148 3 /*
Chris@148 4 Sonic Visualiser
Chris@148 5 An audio file viewer and annotation editor.
Chris@148 6 Centre for Digital Music, Queen Mary, University of London.
Chris@148 7 This file copyright 2006 Chris Cannam.
Chris@148 8
Chris@148 9 This program is free software; you can redistribute it and/or
Chris@148 10 modify it under the terms of the GNU General Public License as
Chris@148 11 published by the Free Software Foundation; either version 2 of the
Chris@148 12 License, or (at your option) any later version. See the file
Chris@148 13 COPYING included with this distribution for more information.
Chris@148 14 */
Chris@148 15
Chris@148 16 #include "WavFileReader.h"
Chris@148 17
Chris@148 18 #include <iostream>
Chris@148 19
Chris@148 20 WavFileReader::WavFileReader(QString path) :
Chris@148 21 m_file(0),
Chris@148 22 m_path(path),
Chris@148 23 m_buffer(0),
Chris@148 24 m_bufsiz(0),
Chris@148 25 m_lastStart(0),
Chris@148 26 m_lastCount(0)
Chris@148 27 {
Chris@148 28 m_frameCount = 0;
Chris@148 29 m_channelCount = 0;
Chris@148 30 m_sampleRate = 0;
Chris@148 31
Chris@148 32 m_fileInfo.format = 0;
Chris@148 33 m_fileInfo.frames = 0;
Chris@148 34 m_file = sf_open(m_path.toLocal8Bit(), SFM_READ, &m_fileInfo);
Chris@148 35
Chris@148 36 if (!m_file || m_fileInfo.frames <= 0 || m_fileInfo.channels <= 0) {
Chris@148 37 std::cerr << "WavFileReader::initialize: Failed to open file ("
Chris@148 38 << sf_strerror(m_file) << ")" << std::endl;
Chris@148 39
Chris@148 40 if (m_file) {
Chris@148 41 m_error = QString("Couldn't load audio file '%1':\n%2")
Chris@148 42 .arg(m_path).arg(sf_strerror(m_file));
Chris@148 43 } else {
Chris@148 44 m_error = QString("Failed to open audio file '%1'")
Chris@148 45 .arg(m_path);
Chris@148 46 }
Chris@148 47 return;
Chris@148 48 }
Chris@148 49
Chris@148 50 m_frameCount = m_fileInfo.frames;
Chris@148 51 m_channelCount = m_fileInfo.channels;
Chris@148 52 m_sampleRate = m_fileInfo.samplerate;
Chris@148 53 }
Chris@148 54
Chris@148 55 WavFileReader::~WavFileReader()
Chris@148 56 {
Chris@148 57 if (m_file) sf_close(m_file);
Chris@148 58 }
Chris@148 59
Chris@148 60 void
Chris@148 61 WavFileReader::getInterleavedFrames(size_t start, size_t count,
Chris@148 62 SampleBlock &results) const
Chris@148 63 {
Chris@148 64 results.clear();
Chris@148 65 if (!m_file || !m_channelCount) return;
Chris@148 66 if (count == 0) return;
Chris@148 67
Chris@148 68 if ((long)start >= m_fileInfo.frames) {
Chris@148 69 return;
Chris@148 70 }
Chris@148 71
Chris@148 72 if (long(start + count) > m_fileInfo.frames) {
Chris@148 73 count = m_fileInfo.frames - start;
Chris@148 74 }
Chris@148 75
Chris@148 76 sf_count_t readCount = 0;
Chris@148 77
Chris@148 78 m_mutex.lock();
Chris@148 79
Chris@148 80 if (start != m_lastStart || count != m_lastCount) {
Chris@148 81
Chris@148 82 if (sf_seek(m_file, start, SEEK_SET) < 0) {
Chris@148 83 m_mutex.unlock();
Chris@148 84 return;
Chris@148 85 }
Chris@148 86
Chris@148 87 if (count * m_fileInfo.channels > m_bufsiz) {
Chris@148 88 // std::cerr << "WavFileReader: Reallocating buffer for " << count
Chris@148 89 // << " frames, " << m_fileInfo.channels << " channels: "
Chris@148 90 // << m_bufsiz << " floats" << std::endl;
Chris@148 91 m_bufsiz = count * m_fileInfo.channels;
Chris@148 92 delete[] m_buffer;
Chris@148 93 m_buffer = new float[m_bufsiz];
Chris@148 94 }
Chris@148 95
Chris@148 96 if ((readCount = sf_readf_float(m_file, m_buffer, count)) < 0) {
Chris@148 97 m_mutex.unlock();
Chris@148 98 return;
Chris@148 99 }
Chris@148 100
Chris@148 101 m_lastStart = start;
Chris@148 102 m_lastCount = readCount;
Chris@148 103 }
Chris@148 104
Chris@148 105 for (size_t i = 0; i < count * m_fileInfo.channels; ++i) {
Chris@148 106 results.push_back(m_buffer[i]);
Chris@148 107 }
Chris@148 108
Chris@148 109 m_mutex.unlock();
Chris@148 110 return;
Chris@148 111 }
Chris@148 112
Chris@157 113 void
Chris@157 114 WavFileReader::getSupportedExtensions(std::set<QString> &extensions)
Chris@157 115 {
Chris@157 116 int count;
Chris@157 117
Chris@157 118 if (sf_command(0, SFC_GET_FORMAT_MAJOR_COUNT, &count, sizeof(count))) {
Chris@157 119 extensions.insert("wav");
Chris@157 120 extensions.insert("aiff");
Chris@157 121 extensions.insert("aif");
Chris@157 122 return;
Chris@157 123 }
Chris@157 124
Chris@157 125 SF_FORMAT_INFO info;
Chris@157 126 for (int i = 0; i < count; ++i) {
Chris@157 127 info.format = i;
Chris@157 128 if (!sf_command(0, SFC_GET_FORMAT_MAJOR, &info, sizeof(info))) {
Chris@157 129 extensions.insert(info.extension);
Chris@157 130 }
Chris@157 131 }
Chris@157 132 }