source: trunk/src/multimedia/audio/qaudioinput_alsa_p.cpp@ 890

Last change on this file since 890 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

  • Property svn:eol-style set to native
File size: 21.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtMultimedia module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42//
43// W A R N I N G
44// -------------
45//
46// This file is not part of the Qt API. It exists for the convenience
47// of other Qt classes. This header file may change from version to
48// version without notice, or even be removed.
49//
50// We mean it.
51//
52
53#include <QtCore/qcoreapplication.h>
54#include "qaudioinput_alsa_p.h"
55#include "qaudiodeviceinfo_alsa_p.h"
56
57QT_BEGIN_NAMESPACE
58
59//#define DEBUG_AUDIO 1
60
61QAudioInputPrivate::QAudioInputPrivate(const QByteArray &device, const QAudioFormat& audioFormat):
62 settings(audioFormat)
63{
64 bytesAvailable = 0;
65 handle = 0;
66 ahandler = 0;
67 access = SND_PCM_ACCESS_RW_INTERLEAVED;
68 pcmformat = SND_PCM_FORMAT_S16;
69 buffer_size = 0;
70 period_size = 0;
71 buffer_time = 100000;
72 period_time = 20000;
73 totalTimeValue = 0;
74 intervalTime = 1000;
75 audioBuffer = 0;
76 errorState = QAudio::NoError;
77 deviceState = QAudio::StoppedState;
78 audioSource = 0;
79 pullMode = true;
80 resuming = false;
81
82 m_device = device;
83
84 timer = new QTimer(this);
85 connect(timer,SIGNAL(timeout()),SLOT(userFeed()));
86}
87
88QAudioInputPrivate::~QAudioInputPrivate()
89{
90 close();
91 disconnect(timer, SIGNAL(timeout()));
92 QCoreApplication::processEvents();
93 delete timer;
94}
95
96QAudio::Error QAudioInputPrivate::error() const
97{
98 return errorState;
99}
100
101QAudio::State QAudioInputPrivate::state() const
102{
103 return deviceState;
104}
105
106
107QAudioFormat QAudioInputPrivate::format() const
108{
109 return settings;
110}
111
112int QAudioInputPrivate::xrun_recovery(int err)
113{
114 int count = 0;
115 bool reset = false;
116
117 if(err == -EPIPE) {
118 errorState = QAudio::UnderrunError;
119 err = snd_pcm_prepare(handle);
120 if(err < 0)
121 reset = true;
122 else {
123 bytesAvailable = checkBytesReady();
124 if (bytesAvailable <= 0)
125 reset = true;
126 }
127
128 } else if((err == -ESTRPIPE)||(err == -EIO)) {
129 errorState = QAudio::IOError;
130 while((err = snd_pcm_resume(handle)) == -EAGAIN){
131 usleep(100);
132 count++;
133 if(count > 5) {
134 reset = true;
135 break;
136 }
137 }
138 if(err < 0) {
139 err = snd_pcm_prepare(handle);
140 if(err < 0)
141 reset = true;
142 }
143 }
144 if(reset) {
145 close();
146 open();
147 snd_pcm_prepare(handle);
148 return 0;
149 }
150 return err;
151}
152
153int QAudioInputPrivate::setFormat()
154{
155 snd_pcm_format_t format = SND_PCM_FORMAT_UNKNOWN;
156
157 if(settings.sampleSize() == 8) {
158 format = SND_PCM_FORMAT_U8;
159 } else if(settings.sampleSize() == 16) {
160 if(settings.sampleType() == QAudioFormat::SignedInt) {
161 if(settings.byteOrder() == QAudioFormat::LittleEndian)
162 format = SND_PCM_FORMAT_S16_LE;
163 else
164 format = SND_PCM_FORMAT_S16_BE;
165 } else if(settings.sampleType() == QAudioFormat::UnSignedInt) {
166 if(settings.byteOrder() == QAudioFormat::LittleEndian)
167 format = SND_PCM_FORMAT_U16_LE;
168 else
169 format = SND_PCM_FORMAT_U16_BE;
170 }
171 } else if(settings.sampleSize() == 24) {
172 if(settings.sampleType() == QAudioFormat::SignedInt) {
173 if(settings.byteOrder() == QAudioFormat::LittleEndian)
174 format = SND_PCM_FORMAT_S24_LE;
175 else
176 format = SND_PCM_FORMAT_S24_BE;
177 } else if(settings.sampleType() == QAudioFormat::UnSignedInt) {
178 if(settings.byteOrder() == QAudioFormat::LittleEndian)
179 format = SND_PCM_FORMAT_U24_LE;
180 else
181 format = SND_PCM_FORMAT_U24_BE;
182 }
183 } else if(settings.sampleSize() == 32) {
184 if(settings.sampleType() == QAudioFormat::SignedInt) {
185 if(settings.byteOrder() == QAudioFormat::LittleEndian)
186 format = SND_PCM_FORMAT_S32_LE;
187 else
188 format = SND_PCM_FORMAT_S32_BE;
189 } else if(settings.sampleType() == QAudioFormat::UnSignedInt) {
190 if(settings.byteOrder() == QAudioFormat::LittleEndian)
191 format = SND_PCM_FORMAT_U32_LE;
192 else
193 format = SND_PCM_FORMAT_U32_BE;
194 } else if(settings.sampleType() == QAudioFormat::Float) {
195 if(settings.byteOrder() == QAudioFormat::LittleEndian)
196 format = SND_PCM_FORMAT_FLOAT_LE;
197 else
198 format = SND_PCM_FORMAT_FLOAT_BE;
199 }
200 } else if(settings.sampleSize() == 64) {
201 if(settings.byteOrder() == QAudioFormat::LittleEndian)
202 format = SND_PCM_FORMAT_FLOAT64_LE;
203 else
204 format = SND_PCM_FORMAT_FLOAT64_BE;
205 }
206
207 return format != SND_PCM_FORMAT_UNKNOWN
208 ? snd_pcm_hw_params_set_format( handle, hwparams, format)
209 : -1;
210}
211
212QIODevice* QAudioInputPrivate::start(QIODevice* device)
213{
214 if(deviceState != QAudio::StoppedState)
215 close();
216
217 if(!pullMode && audioSource) {
218 delete audioSource;
219 }
220
221 if(device) {
222 //set to pull mode
223 pullMode = true;
224 audioSource = device;
225 deviceState = QAudio::ActiveState;
226 } else {
227 //set to push mode
228 pullMode = false;
229 deviceState = QAudio::IdleState;
230 audioSource = new InputPrivate(this);
231 audioSource->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
232 }
233
234 if( !open() )
235 return 0;
236
237 emit stateChanged(deviceState);
238
239 return audioSource;
240}
241
242void QAudioInputPrivate::stop()
243{
244 if(deviceState == QAudio::StoppedState)
245 return;
246
247 deviceState = QAudio::StoppedState;
248
249 close();
250 emit stateChanged(deviceState);
251}
252
253bool QAudioInputPrivate::open()
254{
255#ifdef DEBUG_AUDIO
256 QTime now(QTime::currentTime());
257 qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()";
258#endif
259 clockStamp.restart();
260 timeStamp.restart();
261 elapsedTimeOffset = 0;
262
263 int dir;
264 int err = 0;
265 int count=0;
266 unsigned int freakuency=settings.frequency();
267
268 if (!settings.isValid()) {
269 qWarning("QAudioOutput: open error, invalid format.");
270 } else if (settings.frequency() <= 0) {
271 qWarning("QAudioOutput: open error, invalid sample rate (%d).",
272 settings.frequency());
273 } else {
274 err = -1;
275 }
276
277 if (err == 0) {
278 errorState = QAudio::OpenError;
279 deviceState = QAudio::StoppedState;
280 return false;
281 }
282
283
284 QString dev = QString(QLatin1String(m_device.constData()));
285 QList<QByteArray> devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioInput);
286 if(dev.compare(QLatin1String("default")) == 0) {
287#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
288 dev = QLatin1String(devices.first());
289#else
290 dev = QLatin1String("hw:0,0");
291#endif
292 } else {
293#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
294 dev = QLatin1String(m_device);
295#else
296 int idx = 0;
297 char *name;
298
299 QString shortName = QLatin1String(m_device.mid(m_device.indexOf('=',0)+1).constData());
300
301 while(snd_card_get_name(idx,&name) == 0) {
302 if(qstrncmp(shortName.toLocal8Bit().constData(),name,shortName.length()) == 0)
303 break;
304 idx++;
305 }
306 dev = QString(QLatin1String("hw:%1,0")).arg(idx);
307#endif
308 }
309
310 // Step 1: try and open the device
311 while((count < 5) && (err < 0)) {
312 err=snd_pcm_open(&handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_CAPTURE,0);
313 if(err < 0)
314 count++;
315 }
316 if (( err < 0)||(handle == 0)) {
317 errorState = QAudio::OpenError;
318 deviceState = QAudio::StoppedState;
319 emit stateChanged(deviceState);
320 return false;
321 }
322 snd_pcm_nonblock( handle, 0 );
323
324 // Step 2: Set the desired HW parameters.
325 snd_pcm_hw_params_alloca( &hwparams );
326
327 bool fatal = false;
328 QString errMessage;
329 unsigned int chunks = 8;
330
331 err = snd_pcm_hw_params_any( handle, hwparams );
332 if ( err < 0 ) {
333 fatal = true;
334 errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_any: err = %1").arg(err);
335 }
336 if ( !fatal ) {
337 err = snd_pcm_hw_params_set_rate_resample( handle, hwparams, 1 );
338 if ( err < 0 ) {
339 fatal = true;
340 errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_rate_resample: err = %1").arg(err);
341 }
342 }
343 if ( !fatal ) {
344 err = snd_pcm_hw_params_set_access( handle, hwparams, access );
345 if ( err < 0 ) {
346 fatal = true;
347 errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_access: err = %1").arg(err);
348 }
349 }
350 if ( !fatal ) {
351 err = setFormat();
352 if ( err < 0 ) {
353 fatal = true;
354 errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_format: err = %1").arg(err);
355 }
356 }
357 if ( !fatal ) {
358 err = snd_pcm_hw_params_set_channels( handle, hwparams, (unsigned int)settings.channels() );
359 if ( err < 0 ) {
360 fatal = true;
361 errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_channels: err = %1").arg(err);
362 }
363 }
364 if ( !fatal ) {
365 err = snd_pcm_hw_params_set_rate_near( handle, hwparams, &freakuency, 0 );
366 if ( err < 0 ) {
367 fatal = true;
368 errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_rate_near: err = %1").arg(err);
369 }
370 }
371 if ( !fatal ) {
372 err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, &dir);
373 if ( err < 0 ) {
374 fatal = true;
375 errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_buffer_time_near: err = %1").arg(err);
376 }
377 }
378 if ( !fatal ) {
379 err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, &dir);
380 if ( err < 0 ) {
381 fatal = true;
382 errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_period_time_near: err = %1").arg(err);
383 }
384 }
385 if ( !fatal ) {
386 err = snd_pcm_hw_params_set_periods_near(handle, hwparams, &chunks, &dir);
387 if ( err < 0 ) {
388 fatal = true;
389 errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_periods_near: err = %1").arg(err);
390 }
391 }
392 if ( !fatal ) {
393 err = snd_pcm_hw_params(handle, hwparams);
394 if ( err < 0 ) {
395 fatal = true;
396 errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params: err = %1").arg(err);
397 }
398 }
399 if( err < 0) {
400 qWarning()<<errMessage;
401 errorState = QAudio::OpenError;
402 deviceState = QAudio::StoppedState;
403 emit stateChanged(deviceState);
404 return false;
405 }
406 snd_pcm_hw_params_get_buffer_size(hwparams,&buffer_frames);
407 buffer_size = snd_pcm_frames_to_bytes(handle,buffer_frames);
408 snd_pcm_hw_params_get_period_size(hwparams,&period_frames, &dir);
409 period_size = snd_pcm_frames_to_bytes(handle,period_frames);
410 snd_pcm_hw_params_get_buffer_time(hwparams,&buffer_time, &dir);
411 snd_pcm_hw_params_get_period_time(hwparams,&period_time, &dir);
412
413 // Step 3: Set the desired SW parameters.
414 snd_pcm_sw_params_t *swparams;
415 snd_pcm_sw_params_alloca(&swparams);
416 snd_pcm_sw_params_current(handle, swparams);
417 snd_pcm_sw_params_set_start_threshold(handle,swparams,period_frames);
418 snd_pcm_sw_params_set_stop_threshold(handle,swparams,buffer_frames);
419 snd_pcm_sw_params_set_avail_min(handle, swparams,period_frames);
420 snd_pcm_sw_params(handle, swparams);
421
422 // Step 4: Prepare audio
423 if(audioBuffer == 0)
424 audioBuffer = new char[buffer_size];
425 snd_pcm_prepare( handle );
426 snd_pcm_start(handle);
427
428 // Step 5: Setup timer
429 bytesAvailable = checkBytesReady();
430
431 if(pullMode)
432 connect(audioSource,SIGNAL(readyRead()),this,SLOT(userFeed()));
433
434 // Step 6: Start audio processing
435 chunks = buffer_size/period_size;
436 timer->start(period_time*chunks/2000);
437
438 errorState = QAudio::NoError;
439
440 totalTimeValue = 0;
441
442 return true;
443}
444
445void QAudioInputPrivate::close()
446{
447 timer->stop();
448
449 if ( handle ) {
450 snd_pcm_drop( handle );
451 snd_pcm_close( handle );
452 handle = 0;
453 delete [] audioBuffer;
454 audioBuffer=0;
455 }
456}
457
458int QAudioInputPrivate::checkBytesReady()
459{
460 if(resuming)
461 bytesAvailable = period_size;
462 else if(deviceState != QAudio::ActiveState
463 && deviceState != QAudio::IdleState)
464 bytesAvailable = 0;
465 else {
466 int frames = snd_pcm_avail_update(handle);
467 if (frames < 0) {
468 bytesAvailable = frames;
469 } else {
470 if((int)frames > (int)buffer_frames)
471 frames = buffer_frames;
472 bytesAvailable = snd_pcm_frames_to_bytes(handle, frames);
473 }
474 }
475 return bytesAvailable;
476}
477
478int QAudioInputPrivate::bytesReady() const
479{
480 return qMax(bytesAvailable, 0);
481}
482
483qint64 QAudioInputPrivate::read(char* data, qint64 len)
484{
485 // Read in some audio data and write it to QIODevice, pull mode
486 if ( !handle )
487 return 0;
488
489 // bytesAvaiable is saved as a side effect of checkBytesReady().
490 int bytesToRead = checkBytesReady();
491
492 if (bytesToRead < 0) {
493 // bytesAvailable as negative is error code, try to recover from it.
494 xrun_recovery(bytesToRead);
495 bytesToRead = checkBytesReady();
496 if (bytesToRead < 0) {
497 // recovery failed must stop and set error.
498 close();
499 errorState = QAudio::IOError;
500 deviceState = QAudio::StoppedState;
501 emit stateChanged(deviceState);
502 return 0;
503 }
504 }
505
506 bytesToRead = qMin<qint64>(len, bytesToRead);
507 bytesToRead -= bytesToRead % period_size;
508 int count=0, err = 0;
509 while(count < 5) {
510 int chunks = bytesToRead/period_size;
511 int frames = chunks*period_frames;
512 if(frames > (int)buffer_frames)
513 frames = buffer_frames;
514 int readFrames = snd_pcm_readi(handle, audioBuffer, frames);
515 if (readFrames >= 0) {
516 err = snd_pcm_frames_to_bytes(handle, readFrames);
517#ifdef DEBUG_AUDIO
518 qDebug()<<QString::fromLatin1("read in bytes = %1 (frames=%2)").arg(err).arg(readFrames).toLatin1().constData();
519#endif
520 break;
521 } else if((readFrames == -EAGAIN) || (readFrames == -EINTR)) {
522 errorState = QAudio::IOError;
523 err = 0;
524 break;
525 } else {
526 if(readFrames == -EPIPE) {
527 errorState = QAudio::UnderrunError;
528 err = snd_pcm_prepare(handle);
529 } else if(readFrames == -ESTRPIPE) {
530 err = snd_pcm_prepare(handle);
531 }
532 if(err != 0) break;
533 }
534 count++;
535 }
536 if(err > 0) {
537 // got some send it onward
538#ifdef DEBUG_AUDIO
539 qDebug()<<"frames to write to QIODevice = "<<
540 snd_pcm_bytes_to_frames( handle, (int)err )<<" ("<<err<<") bytes";
541#endif
542 if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
543 return 0;
544 if (pullMode) {
545 qint64 l = audioSource->write(audioBuffer,err);
546 if(l < 0) {
547 close();
548 errorState = QAudio::IOError;
549 deviceState = QAudio::StoppedState;
550 emit stateChanged(deviceState);
551 } else if(l == 0) {
552 if (deviceState != QAudio::IdleState) {
553 errorState = QAudio::NoError;
554 deviceState = QAudio::IdleState;
555 emit stateChanged(deviceState);
556 }
557 } else {
558 bytesAvailable -= err;
559 totalTimeValue += err;
560 resuming = false;
561 if (deviceState != QAudio::ActiveState) {
562 errorState = QAudio::NoError;
563 deviceState = QAudio::ActiveState;
564 emit stateChanged(deviceState);
565 }
566 }
567 return l;
568
569 } else {
570 memcpy(data,audioBuffer,err);
571 bytesAvailable -= err;
572 totalTimeValue += err;
573 resuming = false;
574 if (deviceState != QAudio::ActiveState) {
575 errorState = QAudio::NoError;
576 deviceState = QAudio::ActiveState;
577 emit stateChanged(deviceState);
578 }
579 return err;
580 }
581 }
582 return 0;
583}
584
585void QAudioInputPrivate::resume()
586{
587 if(deviceState == QAudio::SuspendedState) {
588 int err = 0;
589
590 if(handle) {
591 err = snd_pcm_prepare( handle );
592 if(err < 0)
593 xrun_recovery(err);
594
595 err = snd_pcm_start(handle);
596 if(err < 0)
597 xrun_recovery(err);
598
599 bytesAvailable = buffer_size;
600 }
601 resuming = true;
602 deviceState = QAudio::ActiveState;
603 int chunks = buffer_size/period_size;
604 timer->start(period_time*chunks/2000);
605 emit stateChanged(deviceState);
606 }
607}
608
609void QAudioInputPrivate::setBufferSize(int value)
610{
611 buffer_size = value;
612}
613
614int QAudioInputPrivate::bufferSize() const
615{
616 return buffer_size;
617}
618
619int QAudioInputPrivate::periodSize() const
620{
621 return period_size;
622}
623
624void QAudioInputPrivate::setNotifyInterval(int ms)
625{
626 intervalTime = qMax(0, ms);
627}
628
629int QAudioInputPrivate::notifyInterval() const
630{
631 return intervalTime;
632}
633
634qint64 QAudioInputPrivate::processedUSecs() const
635{
636 qint64 result = qint64(1000000) * totalTimeValue /
637 (settings.channels()*(settings.sampleSize()/8)) /
638 settings.frequency();
639
640 return result;
641}
642
643void QAudioInputPrivate::suspend()
644{
645 if(deviceState == QAudio::ActiveState||resuming) {
646 timer->stop();
647 deviceState = QAudio::SuspendedState;
648 emit stateChanged(deviceState);
649 }
650}
651
652void QAudioInputPrivate::userFeed()
653{
654 if(deviceState == QAudio::StoppedState || deviceState == QAudio::SuspendedState)
655 return;
656#ifdef DEBUG_AUDIO
657 QTime now(QTime::currentTime());
658 qDebug()<<now.second()<<"s "<<now.msec()<<"ms :userFeed() IN";
659#endif
660 deviceReady();
661}
662
663bool QAudioInputPrivate::deviceReady()
664{
665 if(pullMode) {
666 // reads some audio data and writes it to QIODevice
667 read(0, buffer_size);
668 } else {
669 // emits readyRead() so user will call read() on QIODevice to get some audio data
670 InputPrivate* a = qobject_cast<InputPrivate*>(audioSource);
671 a->trigger();
672 }
673 bytesAvailable = checkBytesReady();
674
675 if(deviceState != QAudio::ActiveState)
676 return true;
677
678 if (bytesAvailable < 0) {
679 // bytesAvailable as negative is error code, try to recover from it.
680 xrun_recovery(bytesAvailable);
681 bytesAvailable = checkBytesReady();
682 if (bytesAvailable < 0) {
683 // recovery failed must stop and set error.
684 close();
685 errorState = QAudio::IOError;
686 deviceState = QAudio::StoppedState;
687 emit stateChanged(deviceState);
688 return 0;
689 }
690 }
691
692 if(intervalTime && (timeStamp.elapsed() + elapsedTimeOffset) > intervalTime) {
693 emit notify();
694 elapsedTimeOffset = timeStamp.elapsed() + elapsedTimeOffset - intervalTime;
695 timeStamp.restart();
696 }
697 return true;
698}
699
700qint64 QAudioInputPrivate::elapsedUSecs() const
701{
702 if (deviceState == QAudio::StoppedState)
703 return 0;
704
705 return clockStamp.elapsed()*1000;
706}
707
708void QAudioInputPrivate::reset()
709{
710 if(handle)
711 snd_pcm_reset(handle);
712}
713
714void QAudioInputPrivate::drain()
715{
716 if(handle)
717 snd_pcm_drain(handle);
718}
719
720InputPrivate::InputPrivate(QAudioInputPrivate* audio)
721{
722 audioDevice = qobject_cast<QAudioInputPrivate*>(audio);
723}
724
725InputPrivate::~InputPrivate()
726{
727}
728
729qint64 InputPrivate::readData( char* data, qint64 len)
730{
731 return audioDevice->read(data,len);
732}
733
734qint64 InputPrivate::writeData(const char* data, qint64 len)
735{
736 Q_UNUSED(data)
737 Q_UNUSED(len)
738 return 0;
739}
740
741void InputPrivate::trigger()
742{
743 emit readyRead();
744}
745
746QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.