annotate data/fileio/OggVorbisFileReader.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.
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 #ifdef HAVE_OGGZ
lbajardsilogic@0 17 #ifdef HAVE_FISHSOUND
lbajardsilogic@0 18
lbajardsilogic@0 19 #include "OggVorbisFileReader.h"
lbajardsilogic@0 20 #include "base/Profiler.h"
lbajardsilogic@0 21 #include "system/System.h"
lbajardsilogic@0 22
lbajardsilogic@0 23 #include <sys/types.h>
lbajardsilogic@0 24 #include <sys/stat.h>
lbajardsilogic@0 25 //#include <sys/mman.h>
lbajardsilogic@0 26 #include <fcntl.h>
lbajardsilogic@0 27 #include <cmath>
lbajardsilogic@0 28
lbajardsilogic@0 29 #include <QApplication>
lbajardsilogic@0 30 #include <QFileInfo>
lbajardsilogic@0 31 #include <QProgressDialog>
lbajardsilogic@0 32
lbajardsilogic@0 33 static int instances = 0;
lbajardsilogic@0 34
lbajardsilogic@0 35 OggVorbisFileReader::OggVorbisFileReader(QString path, bool showProgress,
lbajardsilogic@0 36 CacheMode mode) :
lbajardsilogic@0 37 CodedAudioFileReader(mode),
lbajardsilogic@0 38 m_path(path),
lbajardsilogic@0 39 m_progress(0),
lbajardsilogic@0 40 m_fileSize(0),
lbajardsilogic@0 41 m_bytesRead(0),
lbajardsilogic@0 42 m_cancelled(false)
lbajardsilogic@0 43 {
lbajardsilogic@0 44 m_frameCount = 0;
lbajardsilogic@0 45 m_channelCount = 0;
lbajardsilogic@0 46 m_sampleRate = 0;
lbajardsilogic@0 47
lbajardsilogic@0 48 std::cerr << "OggVorbisFileReader::OggVorbisFileReader(" << path.toLocal8Bit().data() << "): now have " << (++instances) << " instances" << std::endl;
lbajardsilogic@0 49
lbajardsilogic@0 50 Profiler profiler("OggVorbisFileReader::OggVorbisFileReader", true);
lbajardsilogic@0 51
lbajardsilogic@0 52 QFileInfo info(path);
lbajardsilogic@0 53 m_fileSize = info.size();
lbajardsilogic@0 54
lbajardsilogic@0 55 OGGZ *oggz;
lbajardsilogic@0 56 if (!(oggz = oggz_open(path.toLocal8Bit().data(), OGGZ_READ))) {
lbajardsilogic@0 57 m_error = QString("File %1 is not an OGG file.").arg(path);
lbajardsilogic@0 58 return;
lbajardsilogic@0 59 }
lbajardsilogic@0 60
lbajardsilogic@0 61 FishSoundInfo fsinfo;
lbajardsilogic@0 62 m_fishSound = fish_sound_new(FISH_SOUND_DECODE, &fsinfo);
lbajardsilogic@0 63
lbajardsilogic@0 64 fish_sound_set_decoded_callback(m_fishSound, acceptFrames, this);
lbajardsilogic@0 65 oggz_set_read_callback(oggz, -1, readPacket, this);
lbajardsilogic@0 66
lbajardsilogic@0 67 if (showProgress) {
lbajardsilogic@0 68 m_progress = new QProgressDialog
lbajardsilogic@0 69 (QObject::tr("Decoding %1...").arg(QFileInfo(path).fileName()),
lbajardsilogic@0 70 QObject::tr("Stop"), 0, 100);
lbajardsilogic@0 71 m_progress->hide();
lbajardsilogic@0 72 }
lbajardsilogic@0 73
lbajardsilogic@0 74 while (oggz_read(oggz, 1024) > 0);
lbajardsilogic@0 75
lbajardsilogic@0 76 fish_sound_delete(m_fishSound);
lbajardsilogic@0 77 m_fishSound = 0;
lbajardsilogic@0 78 oggz_close(oggz);
lbajardsilogic@0 79
lbajardsilogic@0 80 if (isDecodeCacheInitialised()) finishDecodeCache();
lbajardsilogic@0 81
lbajardsilogic@0 82 if (showProgress) {
lbajardsilogic@0 83 delete m_progress;
lbajardsilogic@0 84 m_progress = 0;
lbajardsilogic@0 85 }
lbajardsilogic@0 86 }
lbajardsilogic@0 87
lbajardsilogic@0 88 OggVorbisFileReader::~OggVorbisFileReader()
lbajardsilogic@0 89 {
lbajardsilogic@0 90 std::cerr << "OggVorbisFileReader::~OggVorbisFileReader(" << m_path.toLocal8Bit().data() << "): now have " << (--instances) << " instances" << std::endl;
lbajardsilogic@0 91 }
lbajardsilogic@0 92
lbajardsilogic@0 93 int
lbajardsilogic@0 94 OggVorbisFileReader::readPacket(OGGZ *, ogg_packet *packet, long, void *data)
lbajardsilogic@0 95 {
lbajardsilogic@0 96 OggVorbisFileReader *reader = (OggVorbisFileReader *)data;
lbajardsilogic@0 97 FishSound *fs = reader->m_fishSound;
lbajardsilogic@0 98
lbajardsilogic@0 99 fish_sound_prepare_truncation(fs, packet->granulepos, packet->e_o_s);
lbajardsilogic@0 100 fish_sound_decode(fs, packet->packet, packet->bytes);
lbajardsilogic@0 101
lbajardsilogic@0 102 reader->m_bytesRead += packet->bytes;
lbajardsilogic@0 103
lbajardsilogic@0 104 if (reader->m_fileSize > 0 && reader->m_progress) {
lbajardsilogic@0 105 // The number of bytes read by this function is smaller than
lbajardsilogic@0 106 // the file size because of the packet headers
lbajardsilogic@0 107 int progress = lrint(double(reader->m_bytesRead) * 114 /
lbajardsilogic@0 108 double(reader->m_fileSize));
lbajardsilogic@0 109 if (progress > 99) progress = 99;
lbajardsilogic@0 110 if (progress > reader->m_progress->value()) {
lbajardsilogic@0 111 reader->m_progress->setValue(progress);
lbajardsilogic@0 112 reader->m_progress->show();
lbajardsilogic@0 113 reader->m_progress->raise();
lbajardsilogic@0 114 qApp->processEvents();
lbajardsilogic@0 115 if (reader->m_progress->wasCanceled()) {
lbajardsilogic@0 116 reader->m_cancelled = true;
lbajardsilogic@0 117 }
lbajardsilogic@0 118 }
lbajardsilogic@0 119 }
lbajardsilogic@0 120
lbajardsilogic@0 121 if (reader->m_cancelled) return 1;
lbajardsilogic@0 122 return 0;
lbajardsilogic@0 123 }
lbajardsilogic@0 124
lbajardsilogic@0 125 int
lbajardsilogic@0 126 OggVorbisFileReader::acceptFrames(FishSound *fs, float **frames, long nframes,
lbajardsilogic@0 127 void *data)
lbajardsilogic@0 128 {
lbajardsilogic@0 129 OggVorbisFileReader *reader = (OggVorbisFileReader *)data;
lbajardsilogic@0 130
lbajardsilogic@0 131 if (reader->m_channelCount == 0) {
lbajardsilogic@0 132 FishSoundInfo fsinfo;
lbajardsilogic@0 133 fish_sound_command(fs, FISH_SOUND_GET_INFO,
lbajardsilogic@0 134 &fsinfo, sizeof(FishSoundInfo));
lbajardsilogic@0 135 reader->m_channelCount = fsinfo.channels;
lbajardsilogic@0 136 reader->m_sampleRate = fsinfo.samplerate;
lbajardsilogic@0 137 reader->initialiseDecodeCache();
lbajardsilogic@0 138 }
lbajardsilogic@0 139
lbajardsilogic@0 140 if (nframes > 0) {
lbajardsilogic@0 141
lbajardsilogic@0 142 reader->m_frameCount += nframes;
lbajardsilogic@0 143
lbajardsilogic@0 144 for (long i = 0; i < nframes; ++i) {
lbajardsilogic@0 145 for (size_t c = 0; c < reader->m_channelCount; ++c) {
lbajardsilogic@0 146 reader->addSampleToDecodeCache(frames[c][i]);
lbajardsilogic@0 147 // reader->m_data.push_back(frames[c][i]);
lbajardsilogic@0 148 }
lbajardsilogic@0 149 }
lbajardsilogic@0 150
lbajardsilogic@0 151 MUNLOCK_SAMPLEBLOCK(reader->m_data);
lbajardsilogic@0 152 }
lbajardsilogic@0 153
lbajardsilogic@0 154 if (reader->m_cancelled) return 1;
lbajardsilogic@0 155 return 0;
lbajardsilogic@0 156 }
lbajardsilogic@0 157
lbajardsilogic@0 158 void
lbajardsilogic@0 159 OggVorbisFileReader::getSupportedExtensions(std::set<QString> &extensions)
lbajardsilogic@0 160 {
lbajardsilogic@0 161 extensions.insert("ogg");
lbajardsilogic@0 162 }
lbajardsilogic@0 163
lbajardsilogic@0 164 #endif
lbajardsilogic@0 165 #endif