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