Mercurial > hg > svapp
comparison audio/AudioRecordTarget.cpp @ 570:6f54789f3127 3.0-integration
Fix race condition in first-time recording, where adding the recording wave model would prompt the audio play source to note that its channel count had increased (from 0 to, say, 2) and thus to cause the audio device to be reopened, stopping recording. Fix is to make this only happen if channel count increases beyond that of the device, which shouldn't happen in the recording case
author | Chris Cannam |
---|---|
date | Wed, 04 Jan 2017 11:48:03 +0000 |
parents | e348e0c52115 |
children | 9fb190c6521b |
comparison
equal
deleted
inserted
replaced
569:1cc23cee4ebf | 570:6f54789f3127 |
---|---|
100 emit recordDurationChanged(frameToEmit, m_recordSampleRate); | 100 emit recordDurationChanged(frameToEmit, m_recordSampleRate); |
101 } | 101 } |
102 } | 102 } |
103 | 103 |
104 void | 104 void |
105 AudioRecordTarget::setInputLevels(float, float) | 105 AudioRecordTarget::setInputLevels(float left, float right) |
106 { | 106 { |
107 cerr << "AudioRecordTarget::setInputLevels(" << left << "," << right << ")" | |
108 << endl; | |
107 } | 109 } |
108 | 110 |
109 void | 111 void |
110 AudioRecordTarget::modelAboutToBeDeleted() | 112 AudioRecordTarget::modelAboutToBeDeleted() |
111 { | 113 { |
121 { | 123 { |
122 QDir parent(TempDirectory::getInstance()->getContainingPath()); | 124 QDir parent(TempDirectory::getInstance()->getContainingPath()); |
123 QString subdirname("recorded"); | 125 QString subdirname("recorded"); |
124 | 126 |
125 if (!parent.mkpath(subdirname)) { | 127 if (!parent.mkpath(subdirname)) { |
126 cerr << "ERROR: AudioRecordTarget::getRecordContainerFolder: Failed to create recorded dir in \"" << parent.canonicalPath() << "\"" << endl; | 128 SVCERR << "ERROR: AudioRecordTarget::getRecordContainerFolder: Failed to create recorded dir in \"" << parent.canonicalPath() << "\"" << endl; |
127 return ""; | 129 return ""; |
128 } else { | 130 } else { |
129 return parent.filePath(subdirname); | 131 return parent.filePath(subdirname); |
130 } | 132 } |
131 } | 133 } |
136 QDir parent(getRecordContainerFolder()); | 138 QDir parent(getRecordContainerFolder()); |
137 QDateTime now = QDateTime::currentDateTime(); | 139 QDateTime now = QDateTime::currentDateTime(); |
138 QString subdirname = QString("%1").arg(now.toString("yyyyMMdd")); | 140 QString subdirname = QString("%1").arg(now.toString("yyyyMMdd")); |
139 | 141 |
140 if (!parent.mkpath(subdirname)) { | 142 if (!parent.mkpath(subdirname)) { |
141 cerr << "ERROR: AudioRecordTarget::getRecordFolder: Failed to create recorded dir in \"" << parent.canonicalPath() << "\"" << endl; | 143 SVCERR << "ERROR: AudioRecordTarget::getRecordFolder: Failed to create recorded dir in \"" << parent.canonicalPath() << "\"" << endl; |
142 return ""; | 144 return ""; |
143 } else { | 145 } else { |
144 return parent.filePath(subdirname); | 146 return parent.filePath(subdirname); |
145 } | 147 } |
146 } | 148 } |
147 | 149 |
148 WritableWaveFileModel * | 150 WritableWaveFileModel * |
149 AudioRecordTarget::startRecording() | 151 AudioRecordTarget::startRecording() |
150 { | 152 { |
151 { | 153 { |
152 QMutexLocker locker(&m_mutex); | 154 QMutexLocker locker(&m_mutex); |
153 | 155 |
154 if (m_recording) { | 156 if (m_recording) { |
155 cerr << "WARNING: AudioRecordTarget::startRecording: We are already recording" << endl; | 157 SVCERR << "WARNING: AudioRecordTarget::startRecording: We are already recording" << endl; |
156 return 0; | 158 return 0; |
157 } | 159 } |
158 | 160 |
159 m_model = 0; | |
160 m_frameCount = 0; | |
161 | |
162 QString folder = getRecordFolder(); | |
163 if (folder == "") return 0; | |
164 QDir recordedDir(folder); | |
165 | |
166 QDateTime now = QDateTime::currentDateTime(); | |
167 | |
168 // Don't use QDateTime::toString(Qt::ISODate) as the ":" character | |
169 // isn't permitted in filenames on Windows | |
170 QString filename = QString("recorded-%1.wav") | |
171 .arg(now.toString("yyyyMMdd-HHmmss-zzz")); | |
172 | |
173 m_audioFileName = recordedDir.filePath(filename); | |
174 | |
175 m_model = new WritableWaveFileModel(m_recordSampleRate, | |
176 m_recordChannelCount, | |
177 m_audioFileName); | |
178 | |
179 if (!m_model->isOK()) { | |
180 cerr << "ERROR: AudioRecordTarget::startRecording: Recording failed" | |
181 << endl; | |
182 //!!! and throw? | |
183 delete m_model; | |
184 m_model = 0; | 161 m_model = 0; |
185 return 0; | 162 m_frameCount = 0; |
186 } | 163 |
187 | 164 QString folder = getRecordFolder(); |
188 m_recording = true; | 165 if (folder == "") return 0; |
166 QDir recordedDir(folder); | |
167 | |
168 QDateTime now = QDateTime::currentDateTime(); | |
169 | |
170 // Don't use QDateTime::toString(Qt::ISODate) as the ":" character | |
171 // isn't permitted in filenames on Windows | |
172 QString nowString = now.toString("yyyyMMdd-HHmmss-zzz"); | |
173 | |
174 QString filename = tr("recorded-%1.wav").arg(nowString); | |
175 QString label = tr("Recorded %1").arg(nowString); | |
176 | |
177 m_audioFileName = recordedDir.filePath(filename); | |
178 | |
179 m_model = new WritableWaveFileModel(m_recordSampleRate, | |
180 m_recordChannelCount, | |
181 m_audioFileName); | |
182 | |
183 if (!m_model->isOK()) { | |
184 SVCERR << "ERROR: AudioRecordTarget::startRecording: Recording failed" | |
185 << endl; | |
186 //!!! and throw? | |
187 delete m_model; | |
188 m_model = 0; | |
189 return 0; | |
190 } | |
191 | |
192 m_model->setObjectName(label); | |
193 m_recording = true; | |
189 } | 194 } |
190 | 195 |
191 emit recordStatusChanged(true); | 196 emit recordStatusChanged(true); |
192 return m_model; | 197 return m_model; |
193 } | 198 } |
194 | 199 |
195 void | 200 void |
196 AudioRecordTarget::stopRecording() | 201 AudioRecordTarget::stopRecording() |
197 { | 202 { |
198 { | 203 { |
199 QMutexLocker locker(&m_mutex); | 204 QMutexLocker locker(&m_mutex); |
200 if (!m_recording) { | 205 if (!m_recording) { |
201 cerr << "WARNING: AudioRecordTarget::startRecording: Not recording" << endl; | 206 SVCERR << "WARNING: AudioRecordTarget::startRecording: Not recording" << endl; |
202 return; | 207 return; |
203 } | 208 } |
204 | 209 |
205 m_model->writeComplete(); | 210 m_model->writeComplete(); |
206 m_model = 0; | 211 m_model = 0; |
207 m_recording = false; | 212 m_recording = false; |
208 } | 213 } |
209 | 214 |
210 emit recordStatusChanged(false); | 215 emit recordStatusChanged(false); |
211 emit recordCompleted(); | 216 emit recordCompleted(); |
212 } | 217 } |