void MqsConfig::onCreateChannel() { string channel_plugin_name = ((QAction*)sender())->text().toStdString(); ChannelManager::create(channel_plugin_name, this); updateChannels(); }
void MqsConfig::onRemoveEncoder() { string user_defined_encoder_name; QList<QListWidgetItem*> selected_encoders = ui.list_encoders->selectedItems(); user_defined_encoder_name = selected_encoders.at(0)->text().toStdString(); if(user_defined_encoder_name.empty()) return; if(QMessageBox::question(this,"Confirmation","Are you really want to delete channel?",QMessageBox::Yes,QMessageBox::No) == QMessageBox::No) return; QString affected_channels(""); QSqlQuery affected_channels_result = settings->query("SELECT name FROM channel WHERE encoder='%s'", user_defined_encoder_name.c_str()); do { QSqlRecord affected_channel = affected_channels_result.record(); affected_channels += affected_channel.value("name").toString(); }while(affected_channels_result.next()); if(!affected_channels.isEmpty()) { QString question("Next linked channels: " + affected_channels + " will be deleted too. Continue?"); if(QMessageBox::question(this,"Channel dependencies found", question, QMessageBox::Yes,QMessageBox::No) == QMessageBox::No) return; } settings->query("DELETE FROM channel WHERE encoder='%s'", user_defined_encoder_name.c_str()); settings->query("DELETE FROM encoder WHERE name = '%s'", user_defined_encoder_name.c_str()); updateEncoders(); updateChannels(); }
void ofApp::update(){ updateSound(); updateChannels(); updateTcp(); }
caScan2D::caScan2D(QWidget *parent) : QWidget(parent) { m_init = true; m_widthDefined = false; m_heightDefined = false; m_xcptDefined = false; m_ycptDefined = false; m_xnewdataDefined = false; m_ynewdataDefined = false; m_savedata_pathDefined = false; m_savedata_subdirDefined = false; m_savedata_filenameDefined = false; thisSimpleView = false; savedSize = 0; savedWidth = 0; savedHeight = 0; selectionInProgress = false; savedData = (float*) 0; initWidgets(); Xpos = Ypos = 0; scrollArea = (QScrollArea *) 0; mainLayout = new QGridLayout(this); mainLayout->setMargin(0); mainLayout->setSpacing(0); setLayout(mainLayout); setup(); setColormap(spectrum_wavelength); setCustomMap(""); setDiscreteCustomMap(false); setROIChannelsRead(""); setROIChannelsWrite(""); setROIreadType(none); setROIwriteType(none); setROIwritemarkerType(box); setROIreadmarkerType(box); setAccessW(true); installEventFilter(this); scaleFactor = 1.0; UpdatesPerSecond = 0; startTimer(1000); writeTimer = new QTimer(this); connect(writeTimer, SIGNAL(timeout()), this, SLOT(updateChannels())); }
void RssSubscribtionManager::addRssChannel(QString url) { RssSubscribtion* subscribtion = new RssSubscribtion(url, prefs->getDefaultEncoding()); subscribtion->update(); channels.insert(url, subscribtion); connect(&updateTimer, SIGNAL(timeout()), this, SLOT(updateChannels())); }
void pcl::modeler::CloudMeshItem::setProperties() { cloud_mesh_->transform(*translation_x_, *translation_y_, *translation_z_, *rotation_x_, *rotation_y_, *rotation_z_); updateChannels(); }
AudioPortAudio::setupWidget::~setupWidget() { disconnect( &m_setupUtil.m_backendModel, SIGNAL( dataChanged() ), &m_setupUtil, SLOT( updateDevices() ) ); disconnect( &m_setupUtil.m_deviceModel, SIGNAL( dataChanged() ), &m_setupUtil, SLOT( updateChannels() ) ); }
void SBusRxClass::process(void) { uint8_t RxChar, Finished = 0; if(RxSerial) { if(millis8() - StartMs > MAX_FRAME_TIME_MS) { RxState = SBUS_WAIT_FOR_0x0F; } while(RxSerial->available() > 0) { RxChar = RxSerial->read(); switch(RxState) { case SBUS_WAIT_FOR_0x0F: if(RxChar == 0x0F) { StartMs = millis8(); /* Start of frame */ RxIdx = 0; RxState = SBUS_WAIT_FOR_END_OF_DATA; } break; case SBUS_WAIT_FOR_END_OF_DATA: Data[RxIdx] = RxChar; RxIdx++; if(RxIdx >= SBUS_RX_DATA_NB) // 23 { /* Check next byte is 0x00 */ RxState = SBUS_WAIT_FOR_0x00; } break; case SBUS_WAIT_FOR_0x00: if(RxChar == 0x00) { if(RxIdx == SBUS_RX_DATA_NB) // 23 { /* Data received with good synchro */ updateChannels(); Synchro = 0xFF; Finished = 1; } } RxState = SBUS_WAIT_FOR_0x0F; break; } if(Finished) break; } } }
void Control::setValue(float value) { float previousValue = mValue; mValue = std::max<float>(0.0,std::min<float>(1.0,value)); if(mValue != previousValue) { updateChannels(); notifyListeners(previousValue); } }
void MqsConfig::onRemoveChannel() { string user_defined_channel_name; QList<QListWidgetItem*> selected_channels = ui.list_channel->selectedItems(); if(!selected_channels.size()) return; user_defined_channel_name = selected_channels.at(0)->text().toStdString(); if(QMessageBox::question(this,"Confirmation","Are you really want to delete channel?",QMessageBox::Yes,QMessageBox::No) == QMessageBox::No) return; settings->query("DELETE FROM channel WHERE name = '%s'", user_defined_channel_name.c_str()); updateChannels(); }
void IRCSession::processResponse(shared_ptr<IIRCCommand> command) { OS_ASSERT(command != nullptr); switch(command->getType()) { case ircCommandTypeMessage: processCommandMessage(boost::dynamic_pointer_cast<IRCCommandMessage>(command)); break; case ircCommandTypeChannelListStart: invalidateChannels(); break; case ircCommandTypeChannel: { shared_ptr<IRCCommandChannel> commandChannel = boost::dynamic_pointer_cast<IRCCommandChannel>(command); OS_ASSERT(commandChannel != nullptr); validateChannel(commandChannel->getChannelName(), commandChannel->getChannelDescription(), commandChannel->getChannelUsers()); } break; case ircCommandTypeChannelListEnd: updateChannels(true); break; case ircCommandTypeJoin: processCommandJoin(boost::dynamic_pointer_cast<IRCCommandJoin>(command)); break; case ircCommandTypePart: processCommandPart(boost::dynamic_pointer_cast<IRCCommandPart>(command)); break; case ircCommandTypeNames: processCommandNames(boost::dynamic_pointer_cast<IRCCommandNames>(command)); break; case ircCommandTypeEndOfNames: processCommandEndOfNames(boost::dynamic_pointer_cast<IRCCommandEndOfNames>(command)); break; case ircCommandTypeQuit: processCommandQuit(boost::dynamic_pointer_cast<IRCCommandQuit>(command)); break; case ircCommandTypeNick: processCommandNick(boost::dynamic_pointer_cast<IRCCommandNick>(command)); break; case ircCommandTypeMode: processCommandMode(boost::dynamic_pointer_cast<IRCCommandMode>(command)); break; case ircCommandTypeKick: processCommandKick(boost::dynamic_pointer_cast<IRCCommandKick>(command)); break; } }
void AM2400Commander::Panel::doLoad(const Settings::Object::State &s) { if (s.loadInteger("Maximized")) showMaximized(); else if (s.loadInteger("Minimized")) showMinimized(); if (s.loadInteger("W") != NULL) { resize(s.loadInteger("W"), s.loadInteger("H")); parentWidget()->move(s.loadInteger("X"), s.loadInteger("Y")); } ui->inputChannelSpinBox->setValue( s.loadInteger("Input Channel") ); ui->outputChannelSpinBox->setValue( s.loadInteger("Output Channel") ); ui->ampModeButtonGroup->setButton( s.loadInteger("Mode") ); updateChannels(); updateMode( s.loadInteger("Mode") ); }
MqsConfig::MqsConfig(QWidget *parent, Qt::WindowFlags flags) : QWidget(parent, flags) { ui.setupUi(this); updateEncoders(); updateChannels(); updateResolutions(); vector<string> suported_channels = ChannelManager::getSuportedPlugins(); for(unsigned int i = 0; i < suported_channels.size(); ++i) { QAction* act = new QAction(suported_channels[i].c_str(), 0); add_channel_menu.addAction(act); connect(act, SIGNAL(triggered()), this, SLOT(onCreateChannel())); } QSqlRecord plugin_path_rec = settings->query("SELECT value as plugin_path FROM property WHERE name = 'plugin_path'").record(); QSqlRecord screen_shot_path_rec = settings->query("SELECT value as screen_shot_path FROM property WHERE name = 'screen_shot_path'").record(); ui.line_plugin_path->setText(plugin_path_rec.value("plugin_path").toString()); ui.line_screen_shot_path->setText(screen_shot_path_rec.value("screen_shot_path").toString()); QObject::connect(this, SIGNAL(updateMain(GUIUpdate)), parent, SLOT(updateMain(GUIUpdate))); QObject::connect(ui.button_add_channel, SIGNAL(clicked()), this, SLOT(onAddChannel())); QObject::connect(ui.button_edit_channel, SIGNAL(clicked()), this, SLOT(onEditChannel())); QObject::connect(ui.button_remove_channel, SIGNAL(clicked()), this, SLOT(onRemoveChannel())); QObject::connect(ui.button_add_encoder, SIGNAL(clicked()), this, SLOT(onAddEncoder())); QObject::connect(ui.button_edit_encoder, SIGNAL(clicked()), this, SLOT(onEditEncoder())); QObject::connect(ui.button_remove_encoder, SIGNAL(clicked()), this, SLOT(onRemoveEncoder())); QObject::connect(ui.list_resolutions, SIGNAL(itemChanged(QListWidgetItem *)), this, SLOT(onResolutionItemChanged(QListWidgetItem *))); QObject::connect(ui.button_clearall_resolutions, SIGNAL(clicked()), this, SLOT(onClearAllResolutions())); QObject::connect(ui.button_sellectall_resolutions, SIGNAL(clicked()), this, SLOT(onSellectAllResolutions())); QObject::connect(ui.button_loaddefaults_resolutions, SIGNAL(clicked()), this, SLOT(onLoadDefaultResolutions())); QObject::connect(ui.button_add_resolutions, SIGNAL(clicked()), this, SLOT(onAddResolutions())); QObject::connect(ui.button_remove_resolutions, SIGNAL(clicked()), this, SLOT(onRemoveResolutions())); QObject::connect(ui.button_edit_resolutions, SIGNAL(clicked()), this, SLOT(onEditResolutions())); QObject::connect(ui.line_screen_shot_path, SIGNAL(textChanged(const QString &)), this, SLOT(onEditScreenShotPath(const QString &))); QObject::connect(ui.line_plugin_path, SIGNAL(textChanged(const QString &)), this, SLOT(onEditPluginPath(const QString &))); QObject::connect(ui.select_plugins_dir, SIGNAL(clicked()), this, SLOT(onSelectPluginPath())); QObject::connect(ui.select_screenshot_dir, SIGNAL(clicked()), this, SLOT(onSelectScreenShotPath())); QObject::connect(ui.list_encoders, SIGNAL(currentTextChanged(const QString &)), this, SLOT(onEncoderSelect(const QString &))); }
void Board::connectAll() { connect(_conn, SIGNAL(boardChannelsRecv(QMap<int, shared_ptr<BoardChannel> >)), this, SLOT(updateChannels(QMap<int,shared_ptr<BoardChannel> >))); connect(_conn, SIGNAL(boardMessagesRecv(QMap<int,shared_ptr<BoardMessage> >)), this, SLOT(updateMessages(QMap<int,shared_ptr<BoardMessage> >))); connect(this, SIGNAL(addMessageReady(int,QString, int)), _conn, SLOT(boardAddMessage(int,QString,int))); connect(this, SIGNAL(addReplyReady(int,QString)), _conn, SLOT(boardAddReply(int,QString))); connect(this, SIGNAL(editMessageReady(int,QString,int)), _conn, SLOT(boardEditMessage(int,QString,int))); connect(this, SIGNAL(deleteMessageReady(int)), _conn, SLOT(boardDeleteMessage(int))); connect(this, SIGNAL(upMessageReady(int)), _conn, SLOT(boardUpMessage(int))); }
void Axon200Commander::Panel::doLoad( const Settings::Object::State &s ) { if (s.loadInteger("Maximized")) showMaximized(); else if (s.loadInteger("Minimized")) showMinimized(); if (s.loadInteger("W") != NULL) { resize(s.loadInteger("W"), s.loadInteger("H")); parentWidget()->move(s.loadInteger("X"), s.loadInteger("Y")); } mainUI->inputChannelSpinBox->setValue( s.loadInteger("Input Channel") ); mainUI->outputChannelSpinBox->setValue( s.loadInteger("Output Channel") ); mainUI->gainComboBox->setCurrentItem( s.loadInteger("Gain") ); mainUI->configComboBox->setCurrentItem( s.loadInteger("Headstage Config") ); mainUI->ampModeButtonGroup->setButton( s.loadInteger("Mode") ); mainUI->autoModeButton->setOn( s.loadInteger("Auto Mode") ); updateChannels(); updateGains(); updateMode( s.loadInteger("Mode") ); }
void checkBT() { if(readBTPackage()) { data_type = data_buffer[TYPE_POS]; switch(data_type) { case(DATA): pwm_status = data_buffer[STATUS_POS]; memcpy(&bt_data, &data_buffer[DATA_POS], DATA_LENGTH); updateChannels(); break; case(RA): sendDataBT(); break; default: break; } } }
void SDRPostThread::runPFBCH(SDRThreadIQData *data_in) { if (numChannels != data_in->numChannels || sampleRate != data_in->sampleRate) { numChannels = data_in->numChannels; sampleRate = data_in->sampleRate; initPFBChannelizer(); doRefresh.store(true); } size_t dataSize = data_in->data.size(); size_t outSize = data_in->data.size(); if (outSize > dataOut.capacity()) { dataOut.reserve(outSize); } if (outSize != dataOut.size()) { dataOut.resize(outSize); } if (iqDataOutQueue != NULL && !iqDataOutQueue->full()) { DemodulatorThreadIQData *iqDataOut = visualDataBuffers.getBuffer(); bool doVis = false; if (iqVisualQueue != NULL && !iqVisualQueue->full()) { doVis = true; } iqDataOut->setRefCount(1 + (doVis?1:0)); iqDataOut->frequency = data_in->frequency; iqDataOut->sampleRate = data_in->sampleRate; iqDataOut->data.assign(data_in->data.begin(), data_in->data.begin() + dataSize); iqDataOutQueue->push(iqDataOut); if (doVis) { iqVisualQueue->push(iqDataOut); } } if (frequency != data_in->frequency) { frequency = data_in->frequency; doRefresh.store(true); } if (doRefresh.load()) { updateActiveDemodulators(); updateChannels(); doRefresh.store(false); } DemodulatorInstance *activeDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator(); int activeDemodChannel = -1; // Find active demodulators if (nRunDemods) { // channelize data // firpfbch output rate is (input rate / channels) for (int i = 0, iMax = dataSize; i < iMax; i+=numChannels) { firpfbch_crcf_analyzer_execute(channelizer, &data_in->data[i], &dataOut[i]); } for (int i = 0, iMax = numChannels+1; i < iMax; i++) { demodChannelActive[i] = 0; } // Find nearest channel for each demodulator for (size_t i = 0; i < nRunDemods; i++) { DemodulatorInstance *demod = runDemods[i]; demodChannel[i] = getChannelAt(demod->getFrequency()); if (demod == activeDemod) { activeDemodChannel = demodChannel[i]; } } for (size_t i = 0; i < nRunDemods; i++) { // cache channel usage refcounts if (demodChannel[i] >= 0) { demodChannelActive[demodChannel[i]]++; } } // Run channels for (int i = 0; i < numChannels+1; i++) { int doDemodVis = ((activeDemodChannel == i) && (iqActiveDemodVisualQueue != NULL) && !iqActiveDemodVisualQueue->full())?1:0; if (!doDemodVis && demodChannelActive[i] == 0) { continue; } DemodulatorThreadIQData *demodDataOut = buffers.getBuffer(); demodDataOut->setRefCount(demodChannelActive[i] + doDemodVis); demodDataOut->frequency = chanCenters[i]; demodDataOut->sampleRate = chanBw; // Calculate channel buffer size size_t chanDataSize = (outSize/numChannels); if (demodDataOut->data.size() != chanDataSize) { if (demodDataOut->data.capacity() < chanDataSize) { demodDataOut->data.reserve(chanDataSize); } demodDataOut->data.resize(chanDataSize); } int idx = i; // Extra channel wraps lower side band of lowest channel // to fix frequency gap on upper side of spectrum if (i == numChannels) { idx = (numChannels/2); } // prepare channel data buffer if (i == 0) { // Channel 0 requires DC correction if (dcBuf.size() != chanDataSize) { dcBuf.resize(chanDataSize); } for (size_t j = 0; j < chanDataSize; j++) { dcBuf[j] = dataOut[idx]; idx += numChannels; } iirfilt_crcf_execute_block(dcFilter, &dcBuf[0], chanDataSize, &demodDataOut->data[0]); } else { for (size_t j = 0; j < chanDataSize; j++) { demodDataOut->data[j] = dataOut[idx]; idx += numChannels; } } if (doDemodVis) { iqActiveDemodVisualQueue->push(demodDataOut); } for (size_t j = 0; j < nRunDemods; j++) { if (demodChannel[j] == i) { DemodulatorInstance *demod = runDemods[j]; demod->getIQInputDataPipe()->push(demodDataOut); } } } } }
AudioPortAudio::setupWidget::setupWidget( QWidget * _parent ) : AudioDeviceSetupWidget( AudioPortAudio::name(), _parent ) { m_backend = new ComboBox( this, "BACKEND" ); m_backend->setGeometry( 64, 15, 260, 20 ); QLabel * backend_lbl = new QLabel( tr( "BACKEND" ), this ); backend_lbl->setFont( pointSize<7>( backend_lbl->font() ) ); backend_lbl->move( 8, 18 ); m_device = new ComboBox( this, "DEVICE" ); m_device->setGeometry( 64, 35, 260, 20 ); QLabel * dev_lbl = new QLabel( tr( "DEVICE" ), this ); dev_lbl->setFont( pointSize<7>( dev_lbl->font() ) ); dev_lbl->move( 8, 38 ); /* LcdSpinBoxModel * m = new LcdSpinBoxModel( ); m->setRange( DEFAULT_CHANNELS, SURROUND_CHANNELS ); m->setStep( 2 ); m->setValue( ConfigManager::inst()->value( "audioportaudio", "channels" ).toInt() ); m_channels = new LcdSpinBox( 1, this ); m_channels->setModel( m ); m_channels->setLabel( tr( "CHANNELS" ) ); m_channels->move( 308, 20 );*/ // Setup models PaError err = Pa_Initialize(); if( err != paNoError ) { printf( "Couldn't initialize PortAudio: %s\n", Pa_GetErrorText( err ) ); return; } // todo: setup backend model const PaHostApiInfo * hi; for( int i = 0; i < Pa_GetHostApiCount(); ++i ) { hi = Pa_GetHostApiInfo( i ); m_setupUtil.m_backendModel.addItem( hi->name ); } Pa_Terminate(); const QString& backend = ConfigManager::inst()->value( "audioportaudio", "backend" ); const QString& device = ConfigManager::inst()->value( "audioportaudio", "device" ); int i = qMax( 0, m_setupUtil.m_backendModel.findText( backend ) ); m_setupUtil.m_backendModel.setValue( i ); m_setupUtil.updateDevices(); i = qMax( 0, m_setupUtil.m_deviceModel.findText( device ) ); m_setupUtil.m_deviceModel.setValue( i ); connect( &m_setupUtil.m_backendModel, SIGNAL( dataChanged() ), &m_setupUtil, SLOT( updateDevices() ) ); connect( &m_setupUtil.m_deviceModel, SIGNAL( dataChanged() ), &m_setupUtil, SLOT( updateChannels() ) ); m_backend->setModel( &m_setupUtil.m_backendModel ); m_device->setModel( &m_setupUtil.m_deviceModel ); }
void LLAudioEngine::idle(F32 max_decode_time) { if (max_decode_time <= 0.f) { max_decode_time = default_max_decode_time; } // "Update" all of our audio sources, clean up dead ones. // Primarily does position updating, cleanup of unused audio sources. // Also does regeneration of the current priority of each audio source. S32 i; for (i = 0; i < MAX_BUFFERS; i++) { if (mBuffers[i]) { mBuffers[i]->mInUse = false; } } F32 max_priority = -1.f; LLAudioSource *max_sourcep = NULL; // Maximum priority source without a channel source_map::iterator iter; for (iter = mAllSources.begin(); iter != mAllSources.end();) { LLAudioSource *sourcep = iter->second; // Update this source sourcep->update(); sourcep->updatePriority(); if (sourcep->isDone()) { // The source is done playing, clean it up. delete sourcep; mAllSources.erase(iter++); continue; } if (sourcep->isMuted()) { ++iter; continue; } if (!sourcep->getChannel() && sourcep->getCurrentBuffer()) { // We could potentially play this sound if its priority is high enough. if (sourcep->getPriority() > max_priority) { max_priority = sourcep->getPriority(); max_sourcep = sourcep; } } // Move on to the next source iter++; } // Now, do priority-based organization of audio sources. // All channels used, check priorities. // Find channel with lowest priority if (max_sourcep) { LLAudioChannel *channelp = getFreeChannel(max_priority); if (channelp) { //llinfos << "Replacing source in channel due to priority!" << llendl; max_sourcep->setChannel(channelp); channelp->setSource(max_sourcep); if (max_sourcep->isSyncSlave()) { // A sync slave, it doesn't start playing until it's synced up with the master. // Flag this channel as waiting for sync, and return true. channelp->setWaiting(true); } else { channelp->setWaiting(false); channelp->play(); } } } // Do this BEFORE we update the channels // Update the channels to sync up with any changes that the source made, // such as changing what sound was playing. updateChannels(); // Update queued sounds (switch to next queued data if the current has finished playing) for (iter = mAllSources.begin(); iter != mAllSources.end(); ++iter) { // This is lame, instead of this I could actually iterate through all the sources // attached to each channel, since only those with active channels // can have anything interesting happen with their queue? (Maybe not true) LLAudioSource *sourcep = iter->second; if (!sourcep->mQueuedDatap || sourcep->isMuted()) { // Muted, or nothing queued, so we don't care. continue; } LLAudioChannel *channelp = sourcep->getChannel(); if (!channelp) { // This sound isn't playing, so we just process move the queue sourcep->mCurrentDatap = sourcep->mQueuedDatap; sourcep->mQueuedDatap = NULL; // Reset the timer so the source doesn't die. sourcep->mAgeTimer.reset(); // Make sure we have the buffer set up if we just decoded the data if (sourcep->mCurrentDatap) { updateBufferForData(sourcep->mCurrentDatap); } // Actually play the associated data. sourcep->setupChannel(); channelp = sourcep->getChannel(); if (channelp) { channelp->updateBuffer(); sourcep->getChannel()->play(); } continue; } else { // Check to see if the current sound is done playing, or looped. if (!channelp->isPlaying()) { sourcep->mCurrentDatap = sourcep->mQueuedDatap; sourcep->mQueuedDatap = NULL; // Reset the timer so the source doesn't die. sourcep->mAgeTimer.reset(); // Make sure we have the buffer set up if we just decoded the data if (sourcep->mCurrentDatap) { updateBufferForData(sourcep->mCurrentDatap); } // Actually play the associated data. sourcep->setupChannel(); channelp->updateBuffer(); sourcep->getChannel()->play(); } else if (sourcep->isLoop()) { // It's a loop, we need to check and see if we're done with it. if (channelp->mLoopedThisFrame) { sourcep->mCurrentDatap = sourcep->mQueuedDatap; sourcep->mQueuedDatap = NULL; // Actually, should do a time sync so if we're a loop master/slave // we don't drift away. sourcep->setupChannel(); sourcep->getChannel()->play(); } } } } // Lame, update the channels AGAIN. // Update the channels to sync up with any changes that the source made, // such as changing what sound was playing. updateChannels(); // Hack! For now, just use a global sync master; LLAudioSource *sync_masterp = NULL; LLAudioChannel *master_channelp = NULL; F32 max_sm_priority = -1.f; for (iter = mAllSources.begin(); iter != mAllSources.end(); ++iter) { LLAudioSource *sourcep = iter->second; if (sourcep->isMuted()) { continue; } if (sourcep->isSyncMaster()) { if (sourcep->getPriority() > max_sm_priority) { sync_masterp = sourcep; master_channelp = sync_masterp->getChannel(); max_sm_priority = sourcep->getPriority(); } } } if (master_channelp && master_channelp->mLoopedThisFrame) { // Synchronize loop slaves with their masters // Update queued sounds (switch to next queued data if the current has finished playing) for (iter = mAllSources.begin(); iter != mAllSources.end(); ++iter) { LLAudioSource *sourcep = iter->second; if (!sourcep->isSyncSlave()) { // Not a loop slave, we don't need to do anything continue; } LLAudioChannel *channelp = sourcep->getChannel(); if (!channelp) { // Not playing, don't need to bother. continue; } if (!channelp->isPlaying()) { // Now we need to check if our loop master has just looped, and // start playback if that's the case. if (sync_masterp->getChannel()) { channelp->playSynced(master_channelp); channelp->setWaiting(false); } } } } // Sync up everything that the audio engine needs done. commitDeferredChanges(); // Flush unused buffers that are stale enough for (i = 0; i < MAX_BUFFERS; i++) { if (mBuffers[i]) { if (!mBuffers[i]->mInUse && mBuffers[i]->mLastUseTimer.getElapsedTimeF32() > 30.f) { //llinfos << "Flushing unused buffer!" << llendl; mBuffers[i]->mAudioDatap->mBufferp = NULL; delete mBuffers[i]; mBuffers[i] = NULL; } } } // Clear all of the looped flags for the channels for (i = 0; i < MAX_CHANNELS; i++) { if (mChannels[i]) { mChannels[i]->mLoopedThisFrame = false; } } // Decode audio files gAudioDecodeMgrp->processQueue(max_decode_time); // Call this every frame, just in case we somehow // missed picking it up in all the places that can add // or request new data. startNextTransfer(); updateInternetStream(); }
void LLAudioEngine::idle(F32 max_decode_time) { if (max_decode_time <= 0.f) { max_decode_time = default_max_decode_time; } // "Update" all of our audio sources, clean up dead ones. // Primarily does position updating, cleanup of unused audio sources. // Also does regeneration of the current priority of each audio source. S32 i; for (i = 0; i < MAX_BUFFERS; i++) { if (mBuffers[i]) { mBuffers[i]->mInUse = false; } } //Iterate down all queued sources. Remove finished ones, sort active ones by priority. Find highest priority 'master' source if present. LLAudioSource *sync_masterp = NULL; //Highest priority syncmaster LLAudioSource *sync_slavep = NULL; //Highest priority syncslave //Priority queue that will be filled with soundsources that have a high likeleyhood of being able to start [re]playing this idle tick. //Sort order: Primary: priority. Secondary: syncmaster. Tertiary: syncslave std::priority_queue<LLAudioSource*,std::vector<LLAudioSource*,boost::pool_allocator<LLAudioSource*> >,SourcePriorityComparator> queue; //Have to put syncslaves into a temporary list until the syncmaster state is determined. //If the syncmaster might be started, or just looped, insert all pending/looping syncslaves into the priority queue. //If the there is no active syncmaster, then stop any currently looping syncslaves and add none to the priority queue. //This is necessary as any looping soundsources to be stopped, MUST be stopped before iterating down the priority queue. static std::vector<LLAudioSource*> slave_list; slave_list.clear(); //Iterate over all sources. Update their decode or 'done' state, as well as their priorities. //Also add sources that might be able to start playing to the priority queue. //Only sources without channels should be added to priority queue. //Syncslaves must put into the slave list instead of the priority queue. for (source_map::iterator iter = mAllSources.begin(); iter != mAllSources.end();) { LLAudioSource *sourcep = iter->second; //Load/decode/queue pop sourcep->update(); //Done after update, as failure to load might mark source as corrupt, which causes isDone to return true. if (sourcep->isDone()) { // The source is done playing, clean it up. delete sourcep; mAllSources.erase(iter++); continue; } // Increment iter here (it is not used anymore), so we can use continue below to move on to the next source. ++iter; if(!sourcep->isLoop() && sourcep->mPlayedOnce && (!sourcep->mChannelp || !sourcep->mChannelp->isPlaying())) { continue; } LLAudioData *adp = sourcep->getCurrentData(); //If there is no current data at all, or if it hasn't loaded, we must skip this source. if (!adp || !adp->getBuffer()) { continue; } sourcep->updatePriority(); //Calculates current priority. 1.f=ambient. 0.f=muted. Otherwise based off of distance. if (sourcep->getPriority() < F_APPROXIMATELY_ZERO) { // Muted, or nothing queued, or too far, so we don't care. continue; } else if(sourcep->isSyncMaster()) { if(!sync_masterp || sourcep->getPriority() > sync_masterp->getPriority()) { if(sync_masterp && !sync_masterp->getChannel()) queue.push(sync_masterp); //Add lower-priority soundmaster to the queue as a normal sound. sync_masterp = sourcep; //Don't add master to the queue yet. //Add it after highest-priority sound slave is found so we can outrank its priority. continue; } //Else fall through like a normal sound. } else if(sourcep->isSyncSlave()) { if(!sync_slavep || sourcep->getPriority() > sync_slavep->getPriority()) { sync_slavep = sourcep; } //Don't add to the priority queue quite yet. Best primary syncmaster candidate may not have been determined yet. slave_list.push_back(sourcep); continue; } if(sourcep->getChannel()) { //If this is just a regular sound and is currently playing then do nothing special. continue; } //Add to our queue. Highest priority will be at the front. queue.push(sourcep); } // Do this BEFORE we update the channels // Update the channels to sync up with any changes that the source made, // such as changing what sound was playing. updateChannels(); //Loop over all syncsaves. If no syncmaster, stop looping ones, else add ones that need [re]started to the priority queue. //Normally there are zero to one syncslaves, so this loop isn't typically expensive. for(std::vector<LLAudioSource*>::iterator iter=slave_list.begin();iter!=slave_list.end();++iter) { if(!sync_masterp) { //Stop any looping syncslaves. I'm not sure this behavior is correct, but letting looping syncslaves run //off on their own seems wrong. The lsl documentation is unclear. if((*iter)->getChannel() && (*iter)->isLoop()) { (*iter)->getChannel()->cleanup(); } } //If the syncmaster already has a channel and hasn't looped, then we can skip syncslaves this idle tick (there's nothing to do). else if((!sync_masterp->getChannel() || sync_masterp->getChannel()->mLoopedThisFrame)) { //Add syncslaves that we might want to [re]start. if(!(*iter)->getChannel() || (*iter)->isLoop()) queue.push((*iter)); } } if(sync_masterp) { //Syncmaster must have priority greater than or equal to priority of highest priority syncslave. //The case of slave priority equaling master priority is handled in the comparator (SourcePriorityComparator). if(sync_slavep) sync_masterp->setPriority(sync_slavep->getPriority()); if(!sync_masterp->getChannel()) { queue.push(sync_masterp); } } // Dispatch all soundsources. bool syncmaster_started = sync_masterp && sync_masterp->getChannel() && sync_masterp->getChannel()->mLoopedThisFrame; while(!queue.empty()) { LLAudioSource *sourcep = queue.top(); queue.pop(); //If the syncmaster hasn't just started playing, or hasn't just looped then skip this soundslave, //as there's nothing to do with it yet. if (sourcep->isSyncSlave() && !syncmaster_started) { continue; } LLAudioChannel *channelp = sourcep->getChannel(); if (!channelp) { //No more channels. We can break here, as in theory, any lower priority sounds should have had their //channel already stolen. There should be nothing playing, nor playable, when iterating beyond this point. if(!(channelp = getFreeChannel(sourcep->getPriority()))) { break; } //If this is the primary syncmaster that we just started, then [re]start syncslaves further down in the priority queue. //Due to sorting and priority fudgery, the syncmaster is ALWAYS before any syncslaves in this loop. syncmaster_started |= (sourcep == sync_masterp); //setSource calls updateBuffer and update3DPosition, and resets the source mAgeTimer channelp->setSource(sourcep); } if(sourcep->isSyncSlave()) channelp->playSynced(sync_masterp->getChannel()); else channelp->play(); } // Sync up everything that the audio engine needs done. commitDeferredChanges(); // Flush unused buffers that are stale enough for (i = 0; i < MAX_BUFFERS; i++) { if (mBuffers[i]) { if (!mBuffers[i]->mInUse && mBuffers[i]->mLastUseTimer.getElapsedTimeF32() > 30.f) { LL_DEBUGS("AudioEngine") << "Flushing unused buffer!" << LL_ENDL; mBuffers[i]->mAudioDatap->mBufferp = NULL; delete mBuffers[i]; mBuffers[i] = NULL; } } } // Clear all of the looped flags for the channels for (i = 0; i < MAX_CHANNELS; i++) { if (mChannels[i]) { mChannels[i]->mLoopedThisFrame = false; } } // Decode audio files gAudioDecodeMgrp->processQueue(max_decode_time); // Just call here every frame. It makes little sense to call elsewhere, // as it's throttled to one active preloading loading sound at a time anyhow startNextTransfer(); updateInternetStream(); }