Mercurial > hg > svcore
comparison data/fileio/OggVorbisFileReader.cpp @ 263:71dfc6ab3b54
* Threaded mp3/ogg file reading. Not activated yet, as it doesn't work
in context (SV needs to know the duration of its main model at the outset)
| author | Chris Cannam |
|---|---|
| date | Thu, 24 May 2007 16:20:22 +0000 |
| parents | 06ad01f3e553 |
| children | e08f486e8d8c |
comparison
equal
deleted
inserted
replaced
| 262:524bcd89743b | 263:71dfc6ab3b54 |
|---|---|
| 30 #include <QFileInfo> | 30 #include <QFileInfo> |
| 31 #include <QProgressDialog> | 31 #include <QProgressDialog> |
| 32 | 32 |
| 33 static int instances = 0; | 33 static int instances = 0; |
| 34 | 34 |
| 35 OggVorbisFileReader::OggVorbisFileReader(QString path, bool showProgress, | 35 OggVorbisFileReader::OggVorbisFileReader(QString path, |
| 36 DecodeMode decodeMode, | |
| 36 CacheMode mode) : | 37 CacheMode mode) : |
| 37 CodedAudioFileReader(mode), | 38 CodedAudioFileReader(mode), |
| 38 m_path(path), | 39 m_path(path), |
| 39 m_progress(0), | 40 m_progress(0), |
| 40 m_fileSize(0), | 41 m_fileSize(0), |
| 41 m_bytesRead(0), | 42 m_bytesRead(0), |
| 42 m_cancelled(false) | 43 m_cancelled(false), |
| 44 m_decodeThread(0) | |
| 43 { | 45 { |
| 44 m_frameCount = 0; | 46 m_frameCount = 0; |
| 45 m_channelCount = 0; | 47 m_channelCount = 0; |
| 46 m_sampleRate = 0; | 48 m_sampleRate = 0; |
| 47 | 49 |
| 50 Profiler profiler("OggVorbisFileReader::OggVorbisFileReader", true); | 52 Profiler profiler("OggVorbisFileReader::OggVorbisFileReader", true); |
| 51 | 53 |
| 52 QFileInfo info(path); | 54 QFileInfo info(path); |
| 53 m_fileSize = info.size(); | 55 m_fileSize = info.size(); |
| 54 | 56 |
| 55 OGGZ *oggz; | 57 if (!(m_oggz = oggz_open(path.toLocal8Bit().data(), OGGZ_READ))) { |
| 56 if (!(oggz = oggz_open(path.toLocal8Bit().data(), OGGZ_READ))) { | |
| 57 m_error = QString("File %1 is not an OGG file.").arg(path); | 58 m_error = QString("File %1 is not an OGG file.").arg(path); |
| 58 return; | 59 return; |
| 59 } | 60 } |
| 60 | 61 |
| 61 FishSoundInfo fsinfo; | 62 FishSoundInfo fsinfo; |
| 62 m_fishSound = fish_sound_new(FISH_SOUND_DECODE, &fsinfo); | 63 m_fishSound = fish_sound_new(FISH_SOUND_DECODE, &fsinfo); |
| 63 | 64 |
| 64 fish_sound_set_decoded_callback(m_fishSound, acceptFrames, this); | 65 fish_sound_set_decoded_callback(m_fishSound, acceptFrames, this); |
| 65 oggz_set_read_callback(oggz, -1, readPacket, this); | 66 oggz_set_read_callback(m_oggz, -1, readPacket, this); |
| 66 | 67 |
| 67 if (showProgress) { | 68 if (decodeMode == DecodeAtOnce) { |
| 69 | |
| 68 m_progress = new QProgressDialog | 70 m_progress = new QProgressDialog |
| 69 (QObject::tr("Decoding %1...").arg(QFileInfo(path).fileName()), | 71 (QObject::tr("Decoding %1...").arg(QFileInfo(path).fileName()), |
| 70 QObject::tr("Stop"), 0, 100); | 72 QObject::tr("Stop"), 0, 100); |
| 71 m_progress->hide(); | 73 m_progress->hide(); |
| 72 } | |
| 73 | 74 |
| 74 while (oggz_read(oggz, 1024) > 0); | 75 while (oggz_read(m_oggz, 1024) > 0); |
| 76 | |
| 77 fish_sound_delete(m_fishSound); | |
| 78 m_fishSound = 0; | |
| 79 oggz_close(m_oggz); | |
| 80 m_oggz = 0; | |
| 75 | 81 |
| 76 fish_sound_delete(m_fishSound); | 82 if (isDecodeCacheInitialised()) finishDecodeCache(); |
| 77 m_fishSound = 0; | |
| 78 oggz_close(oggz); | |
| 79 | 83 |
| 80 if (isDecodeCacheInitialised()) finishDecodeCache(); | 84 if (decodeMode == DecodeAtOnce) { |
| 85 delete m_progress; | |
| 86 m_progress = 0; | |
| 87 } | |
| 81 | 88 |
| 82 if (showProgress) { | 89 } else { |
| 83 delete m_progress; | 90 |
| 84 m_progress = 0; | 91 while (oggz_read(m_oggz, 1024) > 0 && |
| 92 m_channelCount == 0); | |
| 93 | |
| 94 if (m_channelCount > 0) { | |
| 95 m_decodeThread = new DecodeThread(this); | |
| 96 m_decodeThread->start(); | |
| 97 } | |
| 85 } | 98 } |
| 86 } | 99 } |
| 87 | 100 |
| 88 OggVorbisFileReader::~OggVorbisFileReader() | 101 OggVorbisFileReader::~OggVorbisFileReader() |
| 89 { | 102 { |
| 90 std::cerr << "OggVorbisFileReader::~OggVorbisFileReader(" << m_path.toLocal8Bit().data() << "): now have " << (--instances) << " instances" << std::endl; | 103 std::cerr << "OggVorbisFileReader::~OggVorbisFileReader(" << m_path.toLocal8Bit().data() << "): now have " << (--instances) << " instances" << std::endl; |
| 104 if (m_decodeThread) { | |
| 105 m_decodeThread->wait(); | |
| 106 delete m_decodeThread; | |
| 107 } | |
| 91 } | 108 } |
| 109 | |
| 110 void | |
| 111 OggVorbisFileReader::DecodeThread::run() | |
| 112 { | |
| 113 while (oggz_read(m_reader->m_oggz, 1024) > 0); | |
| 114 | |
| 115 fish_sound_delete(m_reader->m_fishSound); | |
| 116 m_reader->m_fishSound = 0; | |
| 117 oggz_close(m_reader->m_oggz); | |
| 118 m_reader->m_oggz = 0; | |
| 119 | |
| 120 if (m_reader->isDecodeCacheInitialised()) m_reader->finishDecodeCache(); | |
| 121 } | |
| 92 | 122 |
| 93 int | 123 int |
| 94 OggVorbisFileReader::readPacket(OGGZ *, ogg_packet *packet, long, void *data) | 124 OggVorbisFileReader::readPacket(OGGZ *, ogg_packet *packet, long, void *data) |
| 95 { | 125 { |
| 96 OggVorbisFileReader *reader = (OggVorbisFileReader *)data; | 126 OggVorbisFileReader *reader = (OggVorbisFileReader *)data; |
| 142 reader->m_frameCount += nframes; | 172 reader->m_frameCount += nframes; |
| 143 | 173 |
| 144 for (long i = 0; i < nframes; ++i) { | 174 for (long i = 0; i < nframes; ++i) { |
| 145 for (size_t c = 0; c < reader->m_channelCount; ++c) { | 175 for (size_t c = 0; c < reader->m_channelCount; ++c) { |
| 146 reader->addSampleToDecodeCache(frames[c][i]); | 176 reader->addSampleToDecodeCache(frames[c][i]); |
| 147 // reader->m_data.push_back(frames[c][i]); | |
| 148 } | 177 } |
| 149 } | 178 } |
| 150 | 179 |
| 151 MUNLOCK_SAMPLEBLOCK(reader->m_data); | 180 MUNLOCK_SAMPLEBLOCK(reader->m_data); |
| 152 } | 181 } |
