annotate audio/AudioRecordTarget.cpp @ 498:cd9dec2f47e8 recording

Fix suspending/resuming audio device; it wasn't suspending when playback reached the end, only when the user stopped explicitly
author Chris Cannam
date Tue, 22 Sep 2015 17:12:37 +0100
parents 3dbc964f5907
children dcd2afbc1bb7
rev   line source
Chris@476 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@476 2
Chris@476 3 /*
Chris@476 4 Sonic Visualiser
Chris@476 5 An audio file viewer and annotation editor.
Chris@476 6 Centre for Digital Music, Queen Mary, University of London.
Chris@476 7
Chris@476 8 This program is free software; you can redistribute it and/or
Chris@476 9 modify it under the terms of the GNU General Public License as
Chris@476 10 published by the Free Software Foundation; either version 2 of the
Chris@476 11 License, or (at your option) any later version. See the file
Chris@476 12 COPYING included with this distribution for more information.
Chris@476 13 */
Chris@476 14
Chris@476 15 #include "AudioRecordTarget.h"
Chris@476 16
Chris@476 17 #include "base/ViewManagerBase.h"
Chris@476 18 #include "base/TempDirectory.h"
Chris@476 19
Chris@477 20 #include "data/model/WritableWaveFileModel.h"
Chris@476 21
Chris@498 22 #include <bqaudioio/SystemRecordSource.h>
Chris@498 23
Chris@476 24 #include <QDir>
Chris@476 25
Chris@476 26 AudioRecordTarget::AudioRecordTarget(ViewManagerBase *manager,
Chris@476 27 QString clientName) :
Chris@476 28 m_viewManager(manager),
Chris@498 29 m_source(0),
Chris@476 30 m_clientName(clientName.toUtf8().data()),
Chris@476 31 m_recording(false),
Chris@476 32 m_recordSampleRate(44100),
Chris@486 33 m_frameCount(0),
Chris@477 34 m_model(0)
Chris@476 35 {
Chris@476 36 }
Chris@476 37
Chris@476 38 AudioRecordTarget::~AudioRecordTarget()
Chris@476 39 {
Chris@476 40 QMutexLocker locker(&m_mutex);
Chris@476 41 }
Chris@476 42
Chris@476 43 void
Chris@498 44 AudioRecordTarget::setSystemRecordSource(breakfastquay::SystemRecordSource *s)
Chris@498 45 {
Chris@498 46 m_source = s;
Chris@498 47 }
Chris@498 48
Chris@498 49 void
Chris@476 50 AudioRecordTarget::setSystemRecordBlockSize(int sz)
Chris@476 51 {
Chris@476 52 }
Chris@476 53
Chris@476 54 void
Chris@476 55 AudioRecordTarget::setSystemRecordSampleRate(int n)
Chris@476 56 {
Chris@476 57 m_recordSampleRate = n;
Chris@476 58 }
Chris@476 59
Chris@476 60 void
Chris@476 61 AudioRecordTarget::setSystemRecordLatency(int sz)
Chris@476 62 {
Chris@476 63 }
Chris@476 64
Chris@476 65 void
Chris@476 66 AudioRecordTarget::putSamples(int nframes, float **samples)
Chris@476 67 {
Chris@486 68 bool secChanged = false;
Chris@486 69 sv_frame_t frameToEmit = 0;
Chris@486 70
Chris@486 71 {
Chris@486 72 QMutexLocker locker(&m_mutex); //!!! bad here
Chris@486 73 if (!m_recording) return;
Chris@486 74
Chris@486 75 m_model->addSamples(samples, nframes);
Chris@486 76
Chris@486 77 sv_frame_t priorFrameCount = m_frameCount;
Chris@486 78 m_frameCount += nframes;
Chris@486 79
Chris@486 80 RealTime priorRT = RealTime::frame2RealTime
Chris@486 81 (priorFrameCount, m_recordSampleRate);
Chris@486 82 RealTime postRT = RealTime::frame2RealTime
Chris@486 83 (m_frameCount, m_recordSampleRate);
Chris@486 84
Chris@486 85 secChanged = (postRT.sec > priorRT.sec);
Chris@486 86 if (secChanged) frameToEmit = m_frameCount;
Chris@486 87 }
Chris@486 88
Chris@486 89 if (secChanged) {
Chris@486 90 emit recordDurationChanged(frameToEmit, m_recordSampleRate);
Chris@486 91 }
Chris@476 92 }
Chris@476 93
Chris@476 94 void
Chris@476 95 AudioRecordTarget::setInputLevels(float peakLeft, float peakRight)
Chris@476 96 {
Chris@476 97 }
Chris@476 98
Chris@477 99 void
Chris@477 100 AudioRecordTarget::modelAboutToBeDeleted()
Chris@477 101 {
Chris@477 102 QMutexLocker locker(&m_mutex);
Chris@477 103 if (sender() == m_model) {
Chris@477 104 m_model = 0;
Chris@477 105 m_recording = false;
Chris@477 106 }
Chris@477 107 }
Chris@477 108
Chris@483 109 QString
Chris@483 110 AudioRecordTarget::getRecordFolder()
Chris@483 111 {
Chris@483 112 QDir parent(TempDirectory::getInstance()->getContainingPath());
Chris@483 113 QString subdirname = "recorded"; //!!! tr?
Chris@483 114 if (!parent.mkpath(subdirname)) {
Chris@483 115 cerr << "ERROR: AudioRecordTarget::getRecordFolder: Failed to create recorded dir in \"" << parent.canonicalPath() << "\"" << endl;
Chris@483 116 return "";
Chris@483 117 } else {
Chris@483 118 return parent.filePath(subdirname);
Chris@483 119 }
Chris@483 120 }
Chris@483 121
Chris@477 122 WritableWaveFileModel *
Chris@476 123 AudioRecordTarget::startRecording()
Chris@476 124 {
Chris@498 125 if (m_source) m_source->resume();
Chris@498 126
Chris@477 127 {
Chris@476 128 QMutexLocker locker(&m_mutex);
Chris@498 129
Chris@476 130 if (m_recording) {
Chris@476 131 cerr << "WARNING: AudioRecordTarget::startRecording: We are already recording" << endl;
Chris@477 132 return 0;
Chris@476 133 }
Chris@476 134
Chris@477 135 m_model = 0;
Chris@486 136 m_frameCount = 0;
Chris@477 137
Chris@483 138 QString folder = getRecordFolder();
Chris@483 139 if (folder == "") return 0;
Chris@483 140 QDir recordedDir(folder);
Chris@476 141
Chris@480 142 QDateTime now = QDateTime::currentDateTime();
Chris@476 143
Chris@480 144 // Don't use QDateTime::toString(Qt::ISODate) as the ":" character
Chris@480 145 // isn't permitted in filenames on Windows
Chris@480 146 QString filename = QString("recorded-%1.wav")
Chris@480 147 .arg(now.toString("yyyyMMdd-HHmmss-zzz"));
Chris@476 148
Chris@476 149 m_audioFileName = recordedDir.filePath(filename);
Chris@476 150
Chris@477 151 m_model = new WritableWaveFileModel(m_recordSampleRate, 2, m_audioFileName);
Chris@477 152
Chris@477 153 if (!m_model->isOK()) {
Chris@477 154 cerr << "ERROR: AudioRecordTarget::startRecording: Recording failed"
Chris@477 155 << endl;
Chris@476 156 //!!! and throw?
Chris@477 157 delete m_model;
Chris@477 158 m_model = 0;
Chris@477 159 return 0;
Chris@476 160 }
Chris@476 161
Chris@476 162 m_recording = true;
Chris@477 163 }
Chris@477 164
Chris@477 165 emit recordStatusChanged(true);
Chris@477 166 return m_model;
Chris@476 167 }
Chris@476 168
Chris@476 169 void
Chris@476 170 AudioRecordTarget::stopRecording()
Chris@476 171 {
Chris@477 172 {
Chris@476 173 QMutexLocker locker(&m_mutex);
Chris@476 174 if (!m_recording) {
Chris@476 175 cerr << "WARNING: AudioRecordTarget::startRecording: Not recording" << endl;
Chris@476 176 return;
Chris@476 177 }
Chris@476 178
Chris@477 179 m_model->setCompletion(100);
Chris@477 180 m_model = 0;
Chris@476 181 m_recording = false;
Chris@477 182 }
Chris@477 183
Chris@498 184 if (m_source) m_source->suspend();
Chris@498 185
Chris@477 186 emit recordStatusChanged(false);
Chris@476 187 }
Chris@476 188
Chris@476 189