Chris@175
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@175
|
2
|
Chris@175
|
3 /*
|
Chris@175
|
4 Sonic Visualiser
|
Chris@175
|
5 An audio file viewer and annotation editor.
|
Chris@175
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@175
|
7 This file copyright 2006 Chris Cannam.
|
Chris@175
|
8
|
Chris@175
|
9 This program is free software; you can redistribute it and/or
|
Chris@175
|
10 modify it under the terms of the GNU General Public License as
|
Chris@175
|
11 published by the Free Software Foundation; either version 2 of the
|
Chris@175
|
12 License, or (at your option) any later version. See the file
|
Chris@175
|
13 COPYING included with this distribution for more information.
|
Chris@175
|
14 */
|
Chris@175
|
15
|
Chris@175
|
16 #include "WritableWaveFileModel.h"
|
Chris@175
|
17
|
Chris@175
|
18 #include "base/TempDirectory.h"
|
Chris@175
|
19 #include "base/Exceptions.h"
|
Chris@175
|
20
|
Chris@175
|
21 #include "fileio/WavFileWriter.h"
|
Chris@175
|
22 #include "fileio/WavFileReader.h"
|
Chris@175
|
23
|
Chris@175
|
24 #include <QDir>
|
Chris@175
|
25
|
Chris@175
|
26 #include <cassert>
|
Chris@175
|
27 #include <iostream>
|
Chris@175
|
28
|
Chris@175
|
29 WritableWaveFileModel::WritableWaveFileModel(size_t sampleRate,
|
Chris@175
|
30 size_t channels,
|
Chris@175
|
31 QString path) :
|
Chris@175
|
32 m_model(0),
|
Chris@175
|
33 m_writer(0),
|
Chris@175
|
34 m_reader(0),
|
Chris@175
|
35 m_sampleRate(sampleRate),
|
Chris@175
|
36 m_channels(channels),
|
Chris@175
|
37 m_frameCount(0)
|
Chris@175
|
38 {
|
Chris@175
|
39 if (path.isEmpty()) {
|
Chris@175
|
40 try {
|
Chris@175
|
41 QDir dir(TempDirectory::getInstance()->getPath());
|
Chris@175
|
42 path = dir.filePath(QString("written_%1.wav")
|
Chris@175
|
43 .arg((intptr_t)this));
|
Chris@175
|
44 } catch (DirectoryCreationFailed f) {
|
Chris@175
|
45 std::cerr << "WritableWaveFileModel: Failed to create temporary directory" << std::endl;
|
Chris@175
|
46 return;
|
Chris@175
|
47 }
|
Chris@175
|
48 }
|
Chris@175
|
49
|
Chris@175
|
50 m_writer = new WavFileWriter(path, sampleRate, channels);
|
Chris@175
|
51 if (!m_writer->isOK()) {
|
Chris@175
|
52 std::cerr << "WritableWaveFileModel: Error in creating WAV file writer: " << m_writer->getError().toStdString() << std::endl;
|
Chris@175
|
53 delete m_writer;
|
Chris@175
|
54 m_writer = 0;
|
Chris@175
|
55 return;
|
Chris@175
|
56 }
|
Chris@175
|
57 }
|
Chris@175
|
58
|
Chris@175
|
59 WritableWaveFileModel::~WritableWaveFileModel()
|
Chris@175
|
60 {
|
Chris@175
|
61 delete m_model;
|
Chris@175
|
62 delete m_writer;
|
Chris@175
|
63 delete m_reader;
|
Chris@175
|
64 }
|
Chris@175
|
65
|
Chris@175
|
66 bool
|
Chris@175
|
67 WritableWaveFileModel::addSamples(float **samples, size_t count)
|
Chris@175
|
68 {
|
Chris@175
|
69 if (!m_writer) return false;
|
Chris@175
|
70
|
Chris@175
|
71 if (!m_writer->writeSamples(samples, count)) {
|
Chris@175
|
72 std::cerr << "ERROR: WritableWaveFileModel::addSamples: writer failed: " << m_writer->getError().toStdString() << std::endl;
|
Chris@175
|
73 return false;
|
Chris@175
|
74 }
|
Chris@175
|
75
|
Chris@175
|
76 m_frameCount += count;
|
Chris@175
|
77
|
Chris@175
|
78 if (!m_model) {
|
Chris@175
|
79
|
Chris@176
|
80 m_reader = new WavFileReader(m_writer->getPath(), true);
|
Chris@175
|
81 if (!m_reader->getError().isEmpty()) {
|
Chris@175
|
82 std::cerr << "WritableWaveFileModel: Error in creating wave file reader" << std::endl;
|
Chris@175
|
83 delete m_reader;
|
Chris@175
|
84 m_reader = 0;
|
Chris@175
|
85 return false;
|
Chris@175
|
86 }
|
Chris@175
|
87
|
Chris@175
|
88 m_model = new WaveFileModel(m_writer->getPath(), m_reader);
|
Chris@175
|
89 if (!m_model->isOK()) {
|
Chris@175
|
90 std::cerr << "WritableWaveFileModel: Error in creating wave file model" << std::endl;
|
Chris@175
|
91 delete m_model;
|
Chris@175
|
92 m_model = 0;
|
Chris@175
|
93 delete m_reader;
|
Chris@175
|
94 m_reader = 0;
|
Chris@175
|
95 return false;
|
Chris@175
|
96 }
|
Chris@175
|
97 }
|
Chris@175
|
98
|
Chris@175
|
99 static int updateCounter = 0;
|
Chris@175
|
100 if (++updateCounter == 100) {
|
Chris@175
|
101 if (m_reader) m_reader->updateFrameCount();
|
Chris@175
|
102 updateCounter = 0;
|
Chris@175
|
103 }
|
Chris@175
|
104
|
Chris@175
|
105 return true;
|
Chris@175
|
106 }
|
Chris@175
|
107
|
Chris@175
|
108 void
|
Chris@175
|
109 WritableWaveFileModel::sync()
|
Chris@175
|
110 {
|
Chris@176
|
111 //!!! use setCompletion instead
|
Chris@176
|
112 if (m_reader) m_reader->updateDone();
|
Chris@175
|
113 }
|
Chris@175
|
114
|
Chris@175
|
115 bool
|
Chris@175
|
116 WritableWaveFileModel::isOK() const
|
Chris@175
|
117 {
|
Chris@175
|
118 bool ok = (m_model && m_model->isOK());
|
Chris@175
|
119 std::cerr << "WritableWaveFileModel::isOK(): ok = " << ok << std::endl;
|
Chris@175
|
120 return ok;
|
Chris@175
|
121 }
|
Chris@175
|
122
|
Chris@175
|
123 bool
|
Chris@175
|
124 WritableWaveFileModel::isReady(int *completion) const
|
Chris@175
|
125 {
|
Chris@175
|
126 bool ready = (m_model && m_model->isReady(completion));
|
Chris@180
|
127 std::cerr << "WritableWaveFileModel::isReady(): ready = " << ready << ", completion = " << (completion ? *completion : -1) << std::endl;
|
Chris@175
|
128 return ready;
|
Chris@175
|
129 }
|
Chris@175
|
130
|
Chris@175
|
131 size_t
|
Chris@175
|
132 WritableWaveFileModel::getFrameCount() const
|
Chris@175
|
133 {
|
Chris@175
|
134 std::cerr << "WritableWaveFileModel::getFrameCount: count = " << m_frameCount << std::endl;
|
Chris@175
|
135 return m_frameCount;
|
Chris@175
|
136 }
|
Chris@175
|
137
|
Chris@175
|
138 Model *
|
Chris@175
|
139 WritableWaveFileModel::clone() const
|
Chris@175
|
140 {
|
Chris@175
|
141 assert(0); //!!!
|
Chris@175
|
142 }
|
Chris@175
|
143
|
Chris@175
|
144 size_t
|
Chris@175
|
145 WritableWaveFileModel::getValues(int channel, size_t start, size_t end,
|
Chris@175
|
146 float *buffer) const
|
Chris@175
|
147 {
|
Chris@175
|
148 if (!m_model) return 0;
|
Chris@175
|
149 return m_model->getValues(channel, start, end, buffer);
|
Chris@175
|
150 }
|
Chris@175
|
151
|
Chris@175
|
152 size_t
|
Chris@175
|
153 WritableWaveFileModel::getValues(int channel, size_t start, size_t end,
|
Chris@175
|
154 double *buffer) const
|
Chris@175
|
155 {
|
Chris@175
|
156 if (!m_model) return 0;
|
Chris@175
|
157 // std::cerr << "WritableWaveFileModel::getValues(" << channel << ", "
|
Chris@175
|
158 // << start << ", " << end << "): calling model" << std::endl;
|
Chris@175
|
159 return m_model->getValues(channel, start, end, buffer);
|
Chris@175
|
160 }
|
Chris@175
|
161
|
Chris@175
|
162 WritableWaveFileModel::RangeBlock
|
Chris@175
|
163 WritableWaveFileModel::getRanges(size_t channel, size_t start, size_t end,
|
Chris@175
|
164 size_t &blockSize) const
|
Chris@175
|
165 {
|
Chris@175
|
166 if (!m_model) return RangeBlock();
|
Chris@175
|
167 return m_model->getRanges(channel, start, end, blockSize);
|
Chris@175
|
168 }
|
Chris@175
|
169
|
Chris@175
|
170 WritableWaveFileModel::Range
|
Chris@175
|
171 WritableWaveFileModel::getRange(size_t channel, size_t start, size_t end) const
|
Chris@175
|
172 {
|
Chris@175
|
173 if (!m_model) return Range();
|
Chris@175
|
174 return m_model->getRange(channel, start, end);
|
Chris@175
|
175 }
|
Chris@175
|
176
|
Chris@175
|
177 void
|
Chris@175
|
178 WritableWaveFileModel::toXml(QTextStream &out,
|
Chris@175
|
179 QString indent,
|
Chris@175
|
180 QString extraAttributes) const
|
Chris@175
|
181 {
|
Chris@175
|
182 assert(0); //!!!
|
Chris@175
|
183 }
|
Chris@175
|
184
|
Chris@175
|
185 QString
|
Chris@175
|
186 WritableWaveFileModel::toXmlString(QString indent,
|
Chris@175
|
187 QString extraAttributes) const
|
Chris@175
|
188 {
|
Chris@175
|
189 assert(0); //!!!
|
Chris@175
|
190 return "";
|
Chris@175
|
191 }
|
Chris@175
|
192
|