1 /*************************************************************************
2 RecordController.cpp - controller/state matching for the audio recorder
3 -------------------
4 begin : Sat Oct 04 2003
5 copyright : (C) 2003 by Thomas Eschenbacher
6 email : Thomas.Eschenbacher@gmx.de
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18 #include "config.h"
19
20 #include "RecordController.h"
21 #include "RecordState.h"
22
23 //***************************************************************************
RecordController()24 Kwave::RecordController::RecordController()
25 :QObject(),
26 m_state(Kwave::REC_UNINITIALIZED),
27 m_next_state(Kwave::REC_EMPTY),
28 m_trigger_set(false),
29 m_enable_prerecording(false),
30 m_empty(true)
31 {
32 }
33
34 //***************************************************************************
~RecordController()35 Kwave::RecordController::~RecordController()
36 {
37 }
38
39 //***************************************************************************
setInitialized(bool initialized)40 void Kwave::RecordController::setInitialized(bool initialized)
41 {
42 if (initialized) {
43 m_next_state = (m_empty) ? Kwave::REC_EMPTY : Kwave::REC_DONE;
44 emit stateChanged(m_state = Kwave::REC_EMPTY);
45 } else {
46 m_next_state = Kwave::REC_UNINITIALIZED;
47 emit stateChanged(Kwave::REC_UNINITIALIZED);
48 }
49 }
50
51 //***************************************************************************
setEmpty(bool empty)52 void Kwave::RecordController::setEmpty(bool empty)
53 {
54 m_empty = empty;
55 }
56
57 //***************************************************************************
enablePrerecording(bool enable)58 void Kwave::RecordController::enablePrerecording(bool enable)
59 {
60 m_enable_prerecording = enable;
61 }
62
63 //***************************************************************************
actionReset()64 void Kwave::RecordController::actionReset()
65 {
66 switch (m_state) {
67 case Kwave::REC_UNINITIALIZED:
68 // already empty, nothing to do
69 break;
70 case Kwave::REC_RECORDING:
71 #if 0
72 // fall back to REC_WAITING_FOR_TRIGGER
73 m_next_state = Kwave::REC_EMPTY;
74 emit stateChanged(m_state = Kwave::REC_WAITING_FOR_TRIGGER);
75 break;
76 #endif
77 case Kwave::REC_EMPTY:
78 case Kwave::REC_BUFFERING:
79 case Kwave::REC_WAITING_FOR_TRIGGER:
80 case Kwave::REC_PRERECORDING:
81 case Kwave::REC_PAUSED:
82 case Kwave::REC_DONE:
83 bool accepted = true;
84 emit sigReset(accepted);
85 if (accepted) emit stateChanged(m_state = Kwave::REC_EMPTY);
86 break;
87 }
88 }
89
90 //***************************************************************************
actionStop()91 void Kwave::RecordController::actionStop()
92 {
93 switch (m_state) {
94 case Kwave::REC_UNINITIALIZED:
95 case Kwave::REC_EMPTY:
96 case Kwave::REC_DONE:
97 // already stopped, nothing to do
98 break;
99 case Kwave::REC_BUFFERING:
100 case Kwave::REC_WAITING_FOR_TRIGGER:
101 case Kwave::REC_PRERECORDING:
102 // abort, change to REC_EMPTY
103 emit sigStopRecord(0);
104 break;
105 case Kwave::REC_RECORDING:
106 case Kwave::REC_PAUSED:
107 // abort, change to REC_DONE
108 m_next_state = Kwave::REC_DONE;
109 emit sigStopRecord(0);
110 break;
111 }
112 }
113
114 //***************************************************************************
actionPause()115 void Kwave::RecordController::actionPause()
116 {
117 switch (m_state) {
118 case Kwave::REC_UNINITIALIZED:
119 case Kwave::REC_EMPTY:
120 case Kwave::REC_DONE:
121 // what do you want ?
122 break;
123 case Kwave::REC_BUFFERING:
124 case Kwave::REC_WAITING_FOR_TRIGGER:
125 case Kwave::REC_PRERECORDING:
126 // this should never happen
127 qWarning("RecordController::actionPause(): "
128 "state = %s ???", stateName(m_state));
129 break;
130 case Kwave::REC_RECORDING:
131 // pause recording
132 emit stateChanged(m_state = Kwave::REC_PAUSED);
133 break;
134 case Kwave::REC_PAUSED:
135 // continue recording
136 emit stateChanged(m_state = Kwave::REC_RECORDING);
137 break;
138 }
139 }
140
141 //***************************************************************************
actionStart()142 void Kwave::RecordController::actionStart()
143 {
144 switch (m_state) {
145 case Kwave::REC_UNINITIALIZED:
146 break; // impossible
147 case Kwave::REC_EMPTY:
148 case Kwave::REC_DONE:
149 // interpret this as manual trigger
150 emit sigStartRecord();
151 break;
152 case Kwave::REC_BUFFERING:
153 case Kwave::REC_PRERECORDING:
154 case Kwave::REC_WAITING_FOR_TRIGGER:
155 // interpret as "trigger now"
156 m_next_state = Kwave::REC_EMPTY;
157 emit stateChanged(m_state = Kwave::REC_RECORDING);
158 break;
159 case Kwave::REC_PAUSED:
160 // interpret this as "continue"
161 m_next_state = Kwave::REC_RECORDING;
162 emit stateChanged(m_state = Kwave::REC_RECORDING);
163 break;
164 case Kwave::REC_RECORDING:
165 // already recording...
166 m_next_state = Kwave::REC_DONE;
167 break;
168 }
169 }
170
171 //***************************************************************************
deviceRecordStarted()172 void Kwave::RecordController::deviceRecordStarted()
173 {
174 switch (m_state) {
175 case Kwave::REC_UNINITIALIZED:
176 break; // impossible
177 case Kwave::REC_EMPTY:
178 case Kwave::REC_PAUSED:
179 case Kwave::REC_DONE:
180 // continue, pre-recording or trigger
181 m_next_state = (m_empty) ? Kwave::REC_EMPTY : Kwave::REC_DONE;
182 emit stateChanged(m_state = Kwave::REC_BUFFERING);
183 break;
184 case Kwave::REC_BUFFERING:
185 case Kwave::REC_WAITING_FOR_TRIGGER:
186 case Kwave::REC_PRERECORDING:
187 case Kwave::REC_RECORDING:
188 // this should never happen
189 qWarning("RecordController::deviceRecordStarted(): "
190 "state = %s ???", stateName(m_state));
191 break;
192 }
193 }
194
195 //***************************************************************************
deviceBufferFull()196 void Kwave::RecordController::deviceBufferFull()
197 {
198 switch (m_state) {
199 case Kwave::REC_UNINITIALIZED:
200 break; // impossible
201 case Kwave::REC_EMPTY:
202 // we are only "recording" for updating the level
203 // meters and other effects -> no state change
204 break;
205 case Kwave::REC_WAITING_FOR_TRIGGER:
206 case Kwave::REC_PRERECORDING:
207 case Kwave::REC_RECORDING:
208 // this should never happen
209 qWarning("RecordController::deviceBufferFull(): "
210 "state = %s ???", stateName(m_state));
211 break;
212 case Kwave::REC_PAUSED: /* == buffering again after pause */
213 // -> will change to "REC_BUFFERING" soon...
214 break;
215 case Kwave::REC_BUFFERING:
216 if (m_enable_prerecording) {
217 // prerecording was set
218 m_state = Kwave::REC_PRERECORDING;
219 } else if (m_trigger_set) {
220 // trigger was set
221 m_state = Kwave::REC_WAITING_FOR_TRIGGER;
222 } else {
223 // default: just start recording
224 m_next_state = Kwave::REC_DONE;
225 m_state = Kwave::REC_RECORDING;
226 }
227 emit stateChanged(m_state);
228 break;
229 case Kwave::REC_DONE:
230 // might occur when the buffer content is flushed
231 // after a stop
232 break;
233 }
234 }
235
236 //***************************************************************************
enableTrigger(bool enable)237 void Kwave::RecordController::enableTrigger(bool enable)
238 {
239 m_trigger_set = enable;
240 }
241
242 //***************************************************************************
deviceTriggerReached()243 void Kwave::RecordController::deviceTriggerReached()
244 {
245 switch (m_state) {
246 case Kwave::REC_UNINITIALIZED:
247 case Kwave::REC_EMPTY:
248 case Kwave::REC_BUFFERING:
249 case Kwave::REC_RECORDING:
250 case Kwave::REC_PAUSED:
251 case Kwave::REC_DONE:
252 // this should never happen
253 qWarning("RecordController::deviceTriggerReached(): "
254 "state = %s ???", stateName(m_state));
255 break;
256 case Kwave::REC_PRERECORDING:
257 case Kwave::REC_WAITING_FOR_TRIGGER:
258 Q_ASSERT(m_trigger_set);
259 if ((m_enable_prerecording) &&
260 (m_state == Kwave::REC_WAITING_FOR_TRIGGER))
261 {
262 // prerecording was set
263 m_state = Kwave::REC_PRERECORDING;
264 } else {
265 // default: just start recording
266 m_state = Kwave::REC_RECORDING;
267 m_next_state = Kwave::REC_DONE;
268 }
269 emit stateChanged(m_state);
270 break;
271 }
272 }
273
274 //***************************************************************************
deviceRecordStopped(int)275 void Kwave::RecordController::deviceRecordStopped(int)
276 {
277 switch (m_state) {
278 case Kwave::REC_UNINITIALIZED:
279 case Kwave::REC_EMPTY:
280 case Kwave::REC_DONE:
281 // this could happen when an abort occurs during buffering
282 emit stateChanged(m_state);
283 break;
284 case Kwave::REC_BUFFERING:
285 case Kwave::REC_PRERECORDING:
286 case Kwave::REC_WAITING_FOR_TRIGGER:
287 // abort, no real data produced
288 if (m_empty) {
289 emit stateChanged(m_state = Kwave::REC_EMPTY);
290 } else {
291 emit stateChanged(m_state = Kwave::REC_DONE);
292 }
293 break;
294 case Kwave::REC_RECORDING:
295 // recording -> pause or done
296 switch (m_next_state) {
297 case Kwave::REC_EMPTY:
298 // something went wrong when starting the recorder
299 if (m_empty) {
300 emit stateChanged(m_state = Kwave::REC_EMPTY);
301 } else {
302 emit stateChanged(m_state = Kwave::REC_DONE);
303 }
304 break;
305 case Kwave::REC_PAUSED:
306 emit stateChanged(m_state = Kwave::REC_PAUSED);
307 break;
308 case Kwave::REC_DONE:
309 emit stateChanged(m_state = Kwave::REC_DONE);
310 break;
311 default:
312 qWarning("RecordController::deviceRecordStopped(): "
313 "next state = %s ???", stateName(m_next_state));
314 }
315 break;
316 case Kwave::REC_PAUSED:
317 // pause -> done
318 emit stateChanged(m_state = Kwave::REC_DONE);
319 break;
320 }
321 }
322
323 //***************************************************************************
stateName(const Kwave::RecordState state)324 const char *Kwave::RecordController::stateName(const Kwave::RecordState state)
325 {
326 switch (state) {
327 case Kwave::REC_UNINITIALIZED: return "REC_UNINITIALIZED";
328 case Kwave::REC_EMPTY: return "REC_EMPTY";
329 case Kwave::REC_BUFFERING: return "REC_BUFFERING";
330 case Kwave::REC_WAITING_FOR_TRIGGER: return "REC_WAITING_FOR_TRIGGER";
331 case Kwave::REC_PRERECORDING: return "REC_PRERECORDING";
332 case Kwave::REC_RECORDING: return "REC_RECORDING";
333 case Kwave::REC_PAUSED: return "REC_PAUSED";
334 case Kwave::REC_DONE: return "REC_DONE";
335 }
336 return "-INVALID-";
337 }
338
339 //***************************************************************************
340 //***************************************************************************
341