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 }