void StepMotionBlurFilter::SetParameterValue(int32 id, bigtime_t when, const void *value, size_t size) { float tmp; if (!value) return; switch (id) { case P_IMPACT: tmp = *((float*)value); impact = (int32)tmp; BroadcastNewParameterValue(fLastImpactChange, id, &impact, sizeof(int32)); break; case P_STEP: tmp = *((float*)value); step_period = (int32)tmp; BroadcastNewParameterValue(fLastImpactChange, id, &step_period, sizeof(int32)); break; default: break; } fLastImpactChange = when; }
void OffsetFilter::SetParameterValue(int32 id, bigtime_t when, const void *value, size_t size) { float tmp; if (!value) return; switch (id) { case P_DELTA_X: tmp = *((float*)value); DELTA_X = (int32)tmp; BroadcastNewParameterValue(fLastOffSetChange, id, &DELTA_X, sizeof(int32)); break; case P_DELTA_Y: tmp = *((float*)value); DELTA_Y = (int32)tmp; BroadcastNewParameterValue(fLastOffSetChange, id, &DELTA_Y, sizeof(int32)); break; default: break; } fLastOffSetChange = when; }
void EqualizerNode::ParameterEventProcessing(const media_timed_event* event) { float value = 0.0; int32 value32 = 0; int32 id = event->bigdata; size_t size = event->data; bigtime_t now = TimeSource()->Now(); type_code v_type = B_FLOAT_TYPE; BParameter* web_param; for (int i = 0; i < fWeb->CountParameters(); i++) { web_param = fWeb->ParameterAt(i); if (web_param->ID() == id) { v_type=web_param->ValueType(); break; } } if (v_type == B_FLOAT_TYPE) value = *((float*)event->pointer); else if (v_type == B_INT32_TYPE) { value32 = *((int32*)event->pointer); value = (float)value32; } if (id == P_MUTE) { fMute = value32; fMuteLastChanged = now; BroadcastNewParameterValue(now, id, event->pointer, size); } else if (id == P_BYPASS) { fByPass = value32; fByPassLastChanged = now; BroadcastNewParameterValue(now, id, event->pointer, size); } else if (id == P_PREAMP) { if (value != fEqualizer.PreAmp()) { fEqualizer.SetPreAmp(value); fPreAmpLastChanged = now; BroadcastNewParameterValue(now, id, &value, size); } } else if (id >= P_BANDS && id < P_BANDS + fEqualizer.BandCount()) { int band = id - P_BANDS; if (value != fEqualizer.Band(band)) { fEqualizer.SetBand(band, value); fBandsLastChanged[band] = now; BroadcastNewParameterValue(now, id, &value, size); } } }
void VideoProducer::SetParameterValue( int32 id, bigtime_t when, const void *value, size_t size) { status_t err = B_OK; switch (id) { case P_COLOR: if (!value || (size != sizeof(uint32))) return; if (*(uint32 *)value == fColor) return; fColor = *(uint32 *)value; fLastColorChange = when; break; case P_INFO: // forbidden return; default: if (fCamDevice == NULL) return; BAutolock lock(fCamDevice->Locker()); err = fCamDevice->SetParameterValue(id, when, value, size); if ((err < B_OK) && (fCamDevice->Sensor())) { err = fCamDevice->Sensor()->SetParameterValue(id, when, value, size); } } if (err >= B_OK) BroadcastNewParameterValue(when, id, (void *)value, size); }
void _AudioAdapterNode::_broadcastInputFormatParams() { PRINT(("_AudioAdapterNode::_broadcastInputFormatParams()\n")); BroadcastNewParameterValue( 0LL, _AudioAdapterParams::P_INPUT_FORMAT, (void*)&input().format.u.raw_audio.format, 4); BroadcastNewParameterValue( 0LL, _AudioAdapterParams::P_INPUT_CHANNEL_COUNT, (void*)&input().format.u.raw_audio.channel_count, 4); // BroadcastChangedParameter(_AudioAdapterParams::P_INPUT_FORMAT); // BroadcastChangedParameter(_AudioAdapterParams::P_INPUT_CHANNEL_COUNT); }
void FlipTransition::SetParameterValue(int32 id, bigtime_t when, const void *value, size_t size) { float tmp; if (!value) return; switch (id) { case P_STATE: tmp = *((float*)value); TState = (uint32)tmp; BroadcastNewParameterValue(fLastStateChange, id, &TState, sizeof(uint32)); break; case P_X: tmp = *((float*)value); Dx = (uint32)tmp; BroadcastNewParameterValue(fLastStateChange, id, &Dx, sizeof(uint32)); break; case P_Y: tmp = *((float*)value); Dy = (uint32)tmp; BroadcastNewParameterValue(fLastStateChange, id, &Dy, sizeof(uint32)); break; case P_RED: tmp = *((float*)value); Red = (uint32)tmp; BroadcastNewParameterValue(fLastStateChange, id, &Red, sizeof(uint32)); break; case P_GREEN: tmp = *((float*)value); Green = (uint32)tmp; BroadcastNewParameterValue(fLastStateChange, id, &Green, sizeof(uint32)); break; case P_BLUE: tmp = *((float*)value); Blue = (uint32)tmp; BroadcastNewParameterValue(fLastStateChange, id, &Blue, sizeof(uint32)); break; case P_MODE: Mode = *(uint32*)value; BroadcastNewParameterValue(fLastStateChange, id, &Mode, sizeof(uint32)); break; default: break; } fLastStateChange = when; }
void VideoProducer::_UpdateStats() { float fps = (fStats[0].frames - fStats[1].frames) * 1000000LL / (double)(fStats[0].stamp - fStats[1].stamp); float rfps = (fStats[0].actual - fStats[1].actual) * 1000000LL / (double)(fStats[0].stamp - fStats[1].stamp); fInfoString = "FPS: "; fInfoString << fps << " virt, " << rfps << " real, missed: " << fStats[0].missed; memcpy(&fStats[1], &fStats[0], sizeof(fStats[0])); fLastColorChange = system_time(); BroadcastNewParameterValue(fLastColorChange, P_INFO, (void *)fInfoString.String(), fInfoString.Length()+1); }
void ToneProducer::HandleEvent(const media_timed_event* event, bigtime_t lateness, bool realTimeEvent) { // FPRINTF(stderr, "ToneProducer::HandleEvent\n"); switch (event->type) { case BTimedEventQueue::B_START: // don't do anything if we're already running if (RunState() != B_STARTED) { // We want to start sending buffers now, so we set up the buffer-sending bookkeeping // and fire off the first "produce a buffer" event. mFramesSent = 0; mTheta = 0; mStartTime = event->event_time; media_timed_event firstBufferEvent(mStartTime, BTimedEventQueue::B_HANDLE_BUFFER); // Alternatively, we could call HandleEvent() directly with this event, to avoid a trip through // the event queue, like this: // // this->HandleEvent(&firstBufferEvent, 0, false); // EventQueue()->AddEvent(firstBufferEvent); } break; case BTimedEventQueue::B_STOP: FPRINTF(stderr, "Handling B_STOP event\n"); // When we handle a stop, we must ensure that downstream consumers don't // get any more buffers from us. This means we have to flush any pending // buffer-producing events from the queue. EventQueue()->FlushEvents(0, BTimedEventQueue::B_ALWAYS, true, BTimedEventQueue::B_HANDLE_BUFFER); break; case _PARAMETER_EVENT: { size_t dataSize = size_t(event->data); int32 param = int32(event->bigdata); if (dataSize >= sizeof(float)) switch (param) { case FREQUENCY_PARAM: { float newValue = *((float*) event->user_data); if (mFrequency != newValue) // an actual change in the value? { mFrequency = newValue; mFreqLastChanged = TimeSource()->Now(); BroadcastNewParameterValue(mFreqLastChanged, param, &mFrequency, sizeof(mFrequency)); } } break; case GAIN_PARAM: { float newValue = *((float*) event->user_data); if (mGain != newValue) { mGain = newValue; mGainLastChanged = TimeSource()->Now(); BroadcastNewParameterValue(mGainLastChanged, param, &mGain, sizeof(mGain)); } } break; case WAVEFORM_PARAM: { int32 newValue = *((int32*) event->user_data); if (mWaveform != newValue) { mWaveform = newValue; mTheta = 0; // reset the generator parameters when we change waveforms mWaveAscending = true; mWaveLastChanged = TimeSource()->Now(); BroadcastNewParameterValue(mWaveLastChanged, param, &mWaveform, sizeof(mWaveform)); } } break; default: FPRINTF(stderr, "Hmmm... got a B_PARAMETER event for a parameter we don't have? (%" B_PRId32 ")\n", param); break; } } break; case BTimedEventQueue::B_HANDLE_BUFFER: { // make sure we're both started *and* connected before delivering a buffer if (RunState() == BMediaEventLooper::B_STARTED && mOutput.destination != media_destination::null) { // Get the next buffer of data BBuffer* buffer = FillNextBuffer(event->event_time); if (buffer) { // send the buffer downstream if and only if output is enabled status_t err = B_ERROR; if (mOutputEnabled) { err = SendBuffer(buffer, mOutput.source, mOutput.destination); } if (err) { // we need to recycle the buffer ourselves if output is disabled or // if the call to SendBuffer() fails buffer->Recycle(); } } // track how much media we've delivered so far size_t nFrames = mOutput.format.u.raw_audio.buffer_size / (sizeof(float) * mOutput.format.u.raw_audio.channel_count); mFramesSent += nFrames; // The buffer is on its way; now schedule the next one to go bigtime_t nextEvent = mStartTime + bigtime_t(double(mFramesSent) / double(mOutput.format.u.raw_audio.frame_rate) * 1000000.0); media_timed_event nextBufferEvent(nextEvent, BTimedEventQueue::B_HANDLE_BUFFER); EventQueue()->AddEvent(nextBufferEvent); } } break; default: break; } }
void FlangerNode::handleParameterEvent( const media_timed_event* pEvent) { float value = *(float*)pEvent->user_data; int32 id = pEvent->bigdata; size_t size = pEvent->data; bigtime_t now = TimeSource()->Now(); switch(id) { case P_MIX_RATIO: if(value == m_fMixRatio) break; // set m_fMixRatio = value; m_tpMixRatioChanged = now; // broadcast BroadcastNewParameterValue( now, id, &m_fMixRatio, size); break; case P_SWEEP_RATE: if(value == m_fSweepRate) break; // set m_fSweepRate = value; m_tpSweepRateChanged = now; if(m_output.destination != media_destination::null) { m_fThetaInc = calc_sweep_delta( m_format.u.raw_audio, m_fSweepRate); } // broadcast BroadcastNewParameterValue( now, id, &m_fSweepRate, size); break; case P_DELAY: if(value == m_fDelay) break; // set m_fDelay = value; m_tpDelayChanged = now; if(m_output.destination != media_destination::null) { m_fSweepBase = calc_sweep_base( m_format.u.raw_audio, m_fDelay, m_fDepth); } // broadcast BroadcastNewParameterValue( now, id, &m_fDelay, size); break; case P_DEPTH: if(value == m_fDepth) break; // set m_fDepth = value; m_tpDepthChanged = now; if(m_output.destination != media_destination::null) { m_fSweepBase = calc_sweep_base( m_format.u.raw_audio, m_fDelay, m_fDepth); m_fSweepFactor = calc_sweep_factor( m_format.u.raw_audio, m_fDepth); } // broadcast BroadcastNewParameterValue( now, id, &m_fDepth, size); break; case P_FEEDBACK: if(value == m_fFeedback) break; // set m_fFeedback = value; m_tpFeedbackChanged = now; // broadcast BroadcastNewParameterValue( now, id, &m_fFeedback, size); break; } }
void LoggingConsumer::HandleEvent(const media_timed_event *event, bigtime_t /* lateness */, bool /* realTimeEvent */) { log_message logMsg; logMsg.now = TimeSource()->Now(); mLogger->Log(LOG_HANDLE_EVENT, logMsg); switch (event->type) { case BTimedEventQueue::B_HANDLE_BUFFER: { BBuffer* buffer = const_cast<BBuffer*>((BBuffer*) event->pointer); if (buffer) { media_header* hdr = buffer->Header(); if (hdr->destination == mInput.destination.id) { bigtime_t now = TimeSource()->Now(); bigtime_t perf_time = hdr->start_time; // the how_early calculated here doesn't include scheduling latency because // we've already been scheduled to handle the buffer bigtime_t how_early = perf_time - mLatency - now; // logMsg.now is already set logMsg.buffer_data.start_time = perf_time; logMsg.buffer_data.offset = how_early; mLogger->Log(LOG_BUFFER_HANDLED, logMsg); // if the buffer is late, we ignore it and report the fact to the producer // who sent it to us if (how_early < 0) { mLateBuffers++; NotifyLateProducer(mInput.source, -how_early, perf_time); } else { // burn some percentage of our stated latency in CPU time (controlled by // a BParameter). this simulates a user-configurable amount of CPU cost // associated with the consumer. bigtime_t spin_start = ::system_time(); bigtime_t spin_now = spin_start; bigtime_t usecToSpin = bigtime_t(mSpinPercentage / 100.0 * mLatency); while (spin_now - spin_start < usecToSpin) { for (long k = 0; k < 1000000; k++) { /* intentionally blank */ } spin_now = ::system_time(); } } // we're done "processing the buffer;" now we recycle it and return to the loop buffer->Recycle(); } else { //fprintf(stderr, "* Woah! Got a buffer for a different destination!\n"); } } } break; // !!! change to B_PARAMETER as soon as it's available // +++++ e.moon [16jun99] // !!! this can't be right: the parameter value is accessed by the pointer // originally passed to SetParameterValue(). there's no guarantee that // value's still valid, is there? case BTimedEventQueue::B_USER_EVENT: { size_t dataSize = size_t(event->data); int32 param = int32(event->bigdata); logMsg.param.id = param; // handle the message if there's sufficient data provided. we only check against // sizeof(float) because all of our parameters happen to be 4 bytes. if various // parameters took different amounts of data, we'd check the size on a per-parameter // basis. if (dataSize >= sizeof(float)) switch (param) { case LATENCY_PARAM: { float value = *((float*) event->pointer); mLatency = bigtime_t(value* 1000); mLastLatencyChange = logMsg.now; // my latency just changed, so reconfigure the BMediaEventLooper // to give me my events at the proper time SetEventLatency(mLatency); // tell the producer that my latency changed, and broadcast a message // about the parameter change to any applications that may be looking // for it through the BMediaRoster::StartWatching() mechanism. // // if we had more than one input, we'd need to tell *all* producers about // the change in our latency. SendLatencyChange(mInput.source, mInput.destination, EventLatency() + SchedulingLatency()); BroadcastNewParameterValue(logMsg.now, param, &value, sizeof(value)); // log the new latency value, for recordkeeping logMsg.param.value = value; mLogger->Log(LOG_SET_PARAM_HANDLED, logMsg); } break; case CPU_SPIN_PARAM: { float value = *((float*) event->pointer); mSpinPercentage = value; mLastSpinChange = logMsg.now; BroadcastNewParameterValue(logMsg.now, param, &value, sizeof(value)); logMsg.param.value = value; mLogger->Log(LOG_SET_PARAM_HANDLED, logMsg); } break; case PRIORITY_PARAM: { mPriority = *((int32*) event->pointer); // DO NOT use ::set_thead_priority() to directly alter the node's control // thread priority. BMediaEventLooper tracks the priority itself and recalculates // the node's scheduling latency whenever SetPriority() is called. This is VERY // important for correct functioning of a node chain. You should *only* alter a // BMediaEventLooper's priority by calling its SetPriority() method. SetPriority(mPriority); mLastPrioChange = logMsg.now; BroadcastNewParameterValue(logMsg.now, param, &mPriority, sizeof(mPriority)); logMsg.param.value = (float) mPriority; mLogger->Log(LOG_SET_PARAM_HANDLED, logMsg); } break; // log the fact that we "handled" a "set parameter" event for a // nonexistent parameter default: mLogger->Log(LOG_INVALID_PARAM_HANDLED, logMsg); break; } } break; case BTimedEventQueue::B_START: // okay, let's go! mLogger->Log(LOG_START_HANDLED, logMsg); break; case BTimedEventQueue::B_STOP: mLogger->Log(LOG_STOP_HANDLED, logMsg); // stopping implies not handling any more buffers. So, we flush all pending // buffers out of the event queue before returning to the event loop. EventQueue()->FlushEvents(0, BTimedEventQueue::B_ALWAYS, true, BTimedEventQueue::B_HANDLE_BUFFER); break; case BTimedEventQueue::B_SEEK: // seeking the log doesn't make any sense, so we just log that we handled the seek // and return without doing anything else mLogger->Log(LOG_SEEK_HANDLED, logMsg); break; case BTimedEventQueue::B_WARP: // similarly, time warps aren't meaningful to the logger, so just record it and return mLogger->Log(LOG_WARP_HANDLED, logMsg); break; case BTimedEventQueue::B_DATA_STATUS: // we really don't care about the producer's data status, but this is where // we'd do something about it if we did. logMsg.data_status.status = event->data; mLogger->Log(LOG_DATA_STATUS_HANDLED, logMsg); break; default: // hmm, someone enqueued a message that we don't understand. log and ignore it. logMsg.unknown.what = event->type; mLogger->Log(LOG_HANDLE_UNKNOWN, logMsg); break; } }