bool QAudioInputPrivate::deviceReady() { bytesAvailable = bytesReady(); #ifdef DEBUG_AUDIO QTime now(QTime::currentTime()); qDebug()<<now.second()<<"s "<<now.msec()<<"ms :deviceReady() INPUT"; #endif if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState) return true; if(pullMode) { // reads some audio data and writes it to QIODevice read(0,0); } else { // emits readyRead() so user will call read() on QIODevice to get some audio data InputPrivate* a = qobject_cast<InputPrivate*>(audioSource); a->trigger(); } if(intervalTime && (timeStamp.elapsed() + elapsedTimeOffset) > intervalTime) { emit notify(); elapsedTimeOffset = timeStamp.elapsed() + elapsedTimeOffset - intervalTime; timeStamp.restart(); } return true; }
void QAudioInputPrivate::feedback() { #ifdef DEBUG_AUDIO QTime now(QTime::currentTime()); qDebug()<<now.second()<<"s "<<now.msec()<<"ms :feedback() INPUT "<<this; #endif bytesAvailable = bytesReady(); if(!(deviceState==QAudio::StoppedState||deviceState==QAudio::SuspendedState)) emit processMore(); }
void sendPipe(int pipe_num, int replica_num) { int r_index; int bytes_avail = bytesReady(replicas, rep_count, pipe_num); if (bytes_avail == 0) { return; } if (pipe_num == timer_stop_index) { // reset the timer timer_started = false; } for (r_index = 0; r_index < rep_count; r_index++) { if (replica_num == r_index) { int retval; retval = buffToPipe(&(replicas[r_index].vot_pipes[pipe_num]), ext_pipes[pipe_num].fd_out, bytes_avail); } else { fakeToPipe(&(replicas[r_index].vot_pipes[pipe_num]), bytes_avail); } } }
bool QAudioInputPrivate::open() { #ifdef DEBUG_AUDIO QTime now(QTime::currentTime()); qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()"; #endif clockStamp.restart(); timeStamp.restart(); elapsedTimeOffset = 0; int dir; int err=-1; int count=0; unsigned int freakuency=settings.frequency(); QString dev = QString(QLatin1String(m_device.constData())); QList<QByteArray> devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioInput); if(dev.compare(QLatin1String("default")) == 0) { #if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) dev = QLatin1String(devices.first()); #else dev = QLatin1String("hw:0,0"); #endif } else { #if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) dev = QLatin1String(m_device); #else int idx = 0; char *name; QString shortName = QLatin1String(m_device.mid(m_device.indexOf('=',0)+1).constData()); while(snd_card_get_name(idx,&name) == 0) { if(qstrncmp(shortName.toLocal8Bit().constData(),name,shortName.length()) == 0) break; idx++; } dev = QString(QLatin1String("hw:%1,0")).arg(idx); #endif } // Step 1: try and open the device while((count < 5) && (err < 0)) { err=snd_pcm_open(&handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_CAPTURE,0); if(err < 0) count++; } if (( err < 0)||(handle == 0)) { errorState = QAudio::OpenError; deviceState = QAudio::StoppedState; emit stateChanged(deviceState); return false; } snd_pcm_nonblock( handle, 0 ); // Step 2: Set the desired HW parameters. snd_pcm_hw_params_alloca( &hwparams ); bool fatal = false; QString errMessage; unsigned int chunks = 8; err = snd_pcm_hw_params_any( handle, hwparams ); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_any: err = %1").arg(err); } if ( !fatal ) { err = snd_pcm_hw_params_set_rate_resample( handle, hwparams, 1 ); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_rate_resample: err = %1").arg(err); } } if ( !fatal ) { err = snd_pcm_hw_params_set_access( handle, hwparams, access ); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_access: err = %1").arg(err); } } if ( !fatal ) { err = setFormat(); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_format: err = %1").arg(err); } } if ( !fatal ) { err = snd_pcm_hw_params_set_channels( handle, hwparams, (unsigned int)settings.channels() ); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_channels: err = %1").arg(err); } } if ( !fatal ) { err = snd_pcm_hw_params_set_rate_near( handle, hwparams, &freakuency, 0 ); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_rate_near: err = %1").arg(err); } } if ( !fatal ) { err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, &dir); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_buffer_time_near: err = %1").arg(err); } } if ( !fatal ) { err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, &dir); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_period_time_near: err = %1").arg(err); } } if ( !fatal ) { err = snd_pcm_hw_params_set_periods_near(handle, hwparams, &chunks, &dir); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_periods_near: err = %1").arg(err); } } if ( !fatal ) { err = snd_pcm_hw_params(handle, hwparams); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params: err = %1").arg(err); } } if( err < 0) { qWarning()<<errMessage; errorState = QAudio::OpenError; deviceState = QAudio::StoppedState; emit stateChanged(deviceState); return false; } snd_pcm_hw_params_get_buffer_size(hwparams,&buffer_frames); buffer_size = snd_pcm_frames_to_bytes(handle,buffer_frames); snd_pcm_hw_params_get_period_size(hwparams,&period_frames, &dir); period_size = snd_pcm_frames_to_bytes(handle,period_frames); snd_pcm_hw_params_get_buffer_time(hwparams,&buffer_time, &dir); snd_pcm_hw_params_get_period_time(hwparams,&period_time, &dir); // Step 3: Set the desired SW parameters. snd_pcm_sw_params_t *swparams; snd_pcm_sw_params_alloca(&swparams); snd_pcm_sw_params_current(handle, swparams); snd_pcm_sw_params_set_start_threshold(handle,swparams,period_frames); snd_pcm_sw_params_set_stop_threshold(handle,swparams,buffer_frames); snd_pcm_sw_params_set_avail_min(handle, swparams,period_frames); snd_pcm_sw_params(handle, swparams); // Step 4: Prepare audio if(audioBuffer == 0) audioBuffer = new char[buffer_size]; snd_pcm_prepare( handle ); snd_pcm_start(handle); // Step 5: Setup timer bytesAvailable = bytesReady(); if(pullMode) connect(audioSource,SIGNAL(readyRead()),this,SLOT(userFeed())); // Step 6: Start audio processing chunks = buffer_size/period_size; timer->start(period_time*chunks/2000); errorState = QAudio::NoError; deviceState = QAudio::ActiveState; totalTimeValue = 0; return true; }
int frames = snd_pcm_avail_update(handle); if((int)frames > (int)buffer_frames) frames = buffer_frames; return snd_pcm_frames_to_bytes(handle, frames); } qint64 QAudioInputPrivate::read(char* data, qint64 len) { Q_UNUSED(data) Q_UNUSED(len) // Read in some audio data and write it to QIODevice, pull mode if ( !handle ) return 0; bytesAvailable = bytesReady(); int count=0, err = 0; while(count < 5) { int chunks = bytesAvailable/period_size; int frames = chunks*period_frames; if(frames > (int)buffer_frames) frames = buffer_frames; int readFrames = snd_pcm_readi(handle, audioBuffer, frames); if (readFrames >= 0) { err = snd_pcm_frames_to_bytes(handle, readFrames); #ifdef DEBUG_AUDIO qDebug()<<QString::fromLatin1("PULL: read in bytes = %1 (frames=%2)").arg(err).arg(readFrames).toLatin1().constData(); #endif break; } else if((readFrames == -EAGAIN) || (readFrames == -EINTR)) {
void checkSDC(int pipe_num) { int r_index; int bytes_avail = bytesReady(replicas, rep_count, pipe_num); if (bytes_avail == 0) { return; } switch (rep_type) { case SMR: // Only one rep, so pretty much have to trust it sendPipe(pipe_num, 0); return; case DMR: // Can detect, and check what to do if (compareBuffs(&(replicas[0].vot_pipes[pipe_num]), &(replicas[1].vot_pipes[pipe_num]), bytes_avail) != 0) { printf("Voting disagreement: caught SDC in DMR but can't do anything about it.\n"); } sendPipe(pipe_num, 0); return; case TMR: // Send the solution that at least two agree on // TODO: What if buff_count is off? for (r_index = 0; r_index < rep_count; r_index++) { if (compareBuffs(&(replicas[r_index].vot_pipes[pipe_num]), &(replicas[(r_index + 1) % rep_count].vot_pipes[pipe_num]), bytes_avail) == 0) { // If the third doesn't agree, it should be restarted. if (compareBuffs(&(replicas[r_index].vot_pipes[pipe_num]), &(replicas[(r_index + 2) % rep_count].vot_pipes[pipe_num]), bytes_avail) != 0) { int restartee = (r_index + 2) % rep_count; debug_print("Caught SDC: %s : %d\n", controller_name, replicas[restartee].pid); if (DEBUG_PRINT) { // print all three or just two? // Create typed pipes for meta data struct typed_pipe print_pipesA[pipe_count]; struct typed_pipe print_pipesB[pipe_count]; convertVoteToTyped(replicas[r_index].vot_pipes, pipe_count, print_pipesA); convertVoteToTyped(replicas[(r_index + 2) % rep_count].vot_pipes, pipe_count, print_pipesB); // Copy the buffer over char *buffer_A = (char *)malloc(sizeof(char) * MAX_VOTE_PIPE_BUFF); char *buffer_B = (char *)malloc(sizeof(char) * MAX_VOTE_PIPE_BUFF); copyBuffer(&(replicas[r_index].vot_pipes[pipe_num]), buffer_A, bytes_avail); copyBuffer(&(replicas[(r_index + 2) % rep_count].vot_pipes[pipe_num]), buffer_B, bytes_avail); // print them out. printBuffer(&(print_pipesA[pipe_num]), buffer_A, bytes_avail); printBuffer(&(print_pipesB[pipe_num]), buffer_B, bytes_avail); free(buffer_A); free(buffer_B); } restart_prep(restartee, r_index); } else { // If all agree, send and be happy. Otherwise the send is done as part of the restart process sendPipe(pipe_num, r_index); } return; } } printf("VoterD: TMR no two replicas agreed.\n"); } }