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 } |