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 }