2 * Copyright 2012, Gerasim Troeglazov (3dEyes**), 3dEyes@gmail.com.
4 * Distributed under the terms of the MIT License.
9 #include <BufferGroup.h>
10 #include <TimeSource.h>
11 #include <ParameterWeb.h>
25 VSTNode::VSTNode(BMediaAddOn
* addon
, const char* name
, const char* path
)
28 BBufferConsumer(B_MEDIA_RAW_AUDIO
),
29 BBufferProducer(B_MEDIA_RAW_AUDIO
),
33 fOutputMediaEnabled(true),
34 fDownstreamLatency(0),
37 fPlugin
= new VSTPlugin();
38 fPlugin
->LoadModule(path
);
43 VSTNode::AddOn(int32
* id
) const
51 VSTNode::HandleMessage(int32 message
, const void* data
, size_t size
)
53 if((BControllable::HandleMessage(message
, data
, size
) != B_OK
) &&
54 (BBufferConsumer::HandleMessage(message
, data
, size
) != B_OK
) &&
55 (BBufferProducer::HandleMessage(message
, data
, size
) != B_OK
) &&
56 (BControllable::HandleMessage(message
, data
, size
) != B_OK
) ) {
57 BMediaNode::HandleMessage(message
, data
, size
);
60 BMediaNode::HandleBadMessage(message
, data
, size
);
65 VSTNode::NodeRegistered()
67 fPreferredFormat
.type
= B_MEDIA_RAW_AUDIO
;
68 fPreferredFormat
.u
.raw_audio
.buffer_size
= BUFF_SIZE
;
69 fPreferredFormat
.u
.raw_audio
= media_raw_audio_format::wildcard
;
70 fPreferredFormat
.u
.raw_audio
.channel_count
=
71 media_raw_audio_format::wildcard
.channel_count
;
72 fPreferredFormat
.u
.raw_audio
.format
= media_raw_audio_format::B_AUDIO_FLOAT
;
74 fFormat
.type
= B_MEDIA_RAW_AUDIO
;
75 fFormat
.u
.raw_audio
= media_raw_audio_format::wildcard
;
77 fInputMedia
.destination
.port
= ControlPort();
78 fInputMedia
.destination
.id
= ID_AUDIO_INPUT
;
79 fInputMedia
.node
= Node();
80 fInputMedia
.source
= media_source::null
;
81 fInputMedia
.format
= fFormat
;
82 strncpy(fInputMedia
.name
, "Audio Input", B_MEDIA_NAME_LENGTH
);
84 fOutputMedia
.source
.port
= ControlPort();
85 fOutputMedia
.source
.id
= ID_AUDIO_OUTPUT
;
86 fOutputMedia
.node
= Node();
87 fOutputMedia
.destination
= media_destination::null
;
88 fOutputMedia
.format
= fFormat
;
89 strncpy(fOutputMedia
.name
, "Audio Output", B_MEDIA_NAME_LENGTH
);
91 InitParameterValues();
94 SetPriority(B_REAL_TIME_PRIORITY
);
100 VSTNode::GetParameterValue(int32 id
, bigtime_t
* lastChangeTime
, void* value
,
103 if (*size
< sizeof(float) || *size
< sizeof(int32
))
106 type_code v_type
= B_FLOAT_TYPE
;
109 for(int i
= 0; i
< fWeb
->CountParameters(); i
++) {
110 param
= fWeb
->ParameterAt(i
);
111 if(param
->ID() == id
) {
112 v_type
= param
->ValueType();
117 *size
= sizeof(float);
120 *(int32
*)value
= fMute
;
121 *lastChangeTime
= fMuteLastChanged
;
123 } else if (id
== P_BYPASS
) {
124 *(int32
*)value
= fByPass
;
125 *lastChangeTime
= fByPassLastChanged
;
128 int32 idx
= id
- P_PARAM
;
129 if (idx
>= 0 && idx
< fPlugin
->ParametersCount()) {
130 VSTParameter
*param
= fPlugin
->Parameter(idx
);
132 if (v_type
== B_FLOAT_TYPE
)
133 *(float*)value
= param
->Value();
135 if (v_type
== B_INT32_TYPE
)
136 *(int32
*)value
= (int32
)ceil(param
->Value());
138 *lastChangeTime
= param
->LastChangeTime();
146 VSTNode::SetParameterValue(int32 id
, bigtime_t time
, const void* value
,
149 int32 idx
= id
- P_PARAM
;
150 if ((idx
>= 0 && idx
< fPlugin
->ParametersCount()) || id
== P_MUTE
||
152 media_timed_event
ev(time
, BTimedEventQueue::B_PARAMETER
, (void*)value
,
153 BTimedEventQueue::B_NO_CLEANUP
, size
, id
, "VSTParam");
154 //dirty hack for parameter processing (mediakit bug????)
155 ParameterEventProcessing(&ev
);
156 EventQueue()->AddEvent(ev
);
162 VSTNode::BufferReceived(BBuffer
* buffer
)
164 if (buffer
->Header()->destination
!= fInputMedia
.destination
.id
) {
169 if (fOutputMedia
.destination
== media_destination::null
||
170 !fOutputMediaEnabled
) {
175 FilterBuffer(buffer
);
177 status_t err
= SendBuffer(buffer
, fOutputMedia
.source
,
178 fOutputMedia
.destination
);
185 VSTNode::AcceptFormat(const media_destination
&dst
, media_format
* format
)
187 if (dst
!= fInputMedia
.destination
)
188 return B_MEDIA_BAD_DESTINATION
;
190 if (format
->type
!= B_MEDIA_RAW_AUDIO
)
191 return B_MEDIA_BAD_FORMAT
;
194 (fFormat
.u
.raw_audio
.format
!= media_raw_audio_format::wildcard
.format
) ?
195 fFormat
: fPreferredFormat
, *format
);
201 VSTNode::GetNextInput(int32
* cookie
, media_input
* input
)
207 *input
= fInputMedia
;
212 VSTNode::DisposeInputCookie(int32 cookie
)
217 VSTNode::FormatChanged(const media_source
&src
, const media_destination
&dst
,
218 int32 changeTag
, const media_format
&format
)
220 return B_MEDIA_BAD_FORMAT
;
224 VSTNode::ProducerDataStatus(const media_destination
&dst
, int32 status
,
227 if (fOutputMedia
.destination
!= media_destination::null
)
228 SendDataStatus(status
, fOutputMedia
.destination
, when
);
232 VSTNode::GetLatencyFor( const media_destination
&dst
, bigtime_t
* latency
,
233 media_node_id
* outTimeSource
)
235 if (dst
!= fInputMedia
.destination
)
236 return B_MEDIA_BAD_DESTINATION
;
238 *latency
= fDownstreamLatency
+ fProcessLatency
;
239 *outTimeSource
= TimeSource()->ID();
244 VSTNode::Connected(const media_source
& source
,
245 const media_destination
& destination
, const media_format
& format
,
248 if (destination
!= fInputMedia
.destination
)
249 return B_MEDIA_BAD_DESTINATION
;
251 if (fInputMedia
.source
!= media_source::null
)
252 return B_MEDIA_ALREADY_CONNECTED
;
254 fInputMedia
.source
= source
;
255 fInputMedia
.format
= format
;
256 *input
= fInputMedia
;
263 VSTNode::Disconnected(const media_source
&src
, const media_destination
&dst
)
265 if(fInputMedia
.source
!=src
|| dst
!=fInputMedia
.destination
)
268 fInputMedia
.source
= media_source::null
;
270 if(fOutputMedia
.destination
== media_destination::null
)
271 fFormat
.u
.raw_audio
= media_raw_audio_format::wildcard
;
273 fInputMedia
.format
= fFormat
;
278 VSTNode::FormatSuggestionRequested(media_type type
, int32 quality
,
279 media_format
* format
)
281 if (type
!= B_MEDIA_RAW_AUDIO
)
282 return B_MEDIA_BAD_FORMAT
;
284 if (fFormat
.u
.raw_audio
.format
!= media_raw_audio_format::wildcard
.format
)
287 *format
= fPreferredFormat
;
293 VSTNode::FormatProposal(const media_source
&src
, media_format
* format
)
295 if (src
!= fOutputMedia
.source
)
296 return B_MEDIA_BAD_SOURCE
;
298 if (format
->type
!= B_MEDIA_RAW_AUDIO
)
299 return B_MEDIA_BAD_FORMAT
;
302 (fFormat
.u
.raw_audio
.format
!= media_raw_audio_format::wildcard
.format
) ?
303 fFormat
: fPreferredFormat
, *format
);
309 VSTNode::FormatChangeRequested(const media_source
&src
,
310 const media_destination
&dst
, media_format
* format
, int32
* _deprecated_
)
312 return B_MEDIA_BAD_FORMAT
;
316 VSTNode::LateNoticeReceived(const media_source
&src
,
317 bigtime_t late
, bigtime_t when
)
319 if (src
!= fOutputMedia
.source
|| fInputMedia
.source
== media_source::null
)
322 NotifyLateProducer(fInputMedia
.source
, late
, when
);
326 VSTNode::GetNextOutput(int32
*cookie
, media_output
* output
)
332 *output
= fOutputMedia
;
337 VSTNode::DisposeOutputCookie(int32 cookie
)
343 VSTNode::SetBufferGroup(const media_source
&src
, BBufferGroup
* group
)
348 if (src
!= fOutputMedia
.source
)
349 return B_MEDIA_BAD_SOURCE
;
351 if (fInputMedia
.source
== media_source::null
)
354 ret
= SetOutputBuffersFor(fInputMedia
.source
, fInputMedia
.destination
,
355 group
, 0, &changeTag
);
361 VSTNode::PrepareToConnect( const media_source
&src
, const media_destination
&dst
,
362 media_format
* format
, media_source
* out_source
, char* name
)
366 if (src
!= fOutputMedia
.source
)
367 return B_MEDIA_BAD_SOURCE
;
369 if (format
->type
!= B_MEDIA_RAW_AUDIO
)
370 return B_MEDIA_BAD_FORMAT
;
372 if (fOutputMedia
.destination
!= media_destination::null
)
373 return B_MEDIA_ALREADY_CONNECTED
;
375 ret
= ValidateFormat(
376 (fFormat
.u
.raw_audio
.format
!= media_raw_audio_format::wildcard
.format
) ?
377 fFormat
: fPreferredFormat
, *format
);
382 SetOutputFormat(*format
);
384 fOutputMedia
.destination
= dst
;
385 fOutputMedia
.format
= *format
;
387 *out_source
= fOutputMedia
.source
;
388 strncpy(name
, fOutputMedia
.name
, B_MEDIA_NAME_LENGTH
);
394 VSTNode::Connect(status_t status
, const media_source
&src
,
395 const media_destination
&dst
, const media_format
&format
, char* name
)
398 fOutputMedia
.destination
= media_destination::null
;
402 strncpy(name
, fOutputMedia
.name
, B_MEDIA_NAME_LENGTH
);
403 fOutputMedia
.destination
= dst
;
406 media_node_id timeSource
;
407 FindLatencyFor(fOutputMedia
.destination
, &fDownstreamLatency
, &timeSource
);
411 fProcessLatency
= GetFilterLatency();
412 SetEventLatency(fDownstreamLatency
+ fProcessLatency
);
414 if (fInputMedia
.source
!= media_source::null
) {
415 SendLatencyChange(fInputMedia
.source
, fInputMedia
.destination
,
416 EventLatency()+SchedulingLatency());
419 bigtime_t duration
= 0;
421 int sample_size
= (fFormat
.u
.raw_audio
.format
& 0xf)*
422 fFormat
.u
.raw_audio
.channel_count
;
423 if (fFormat
.u
.raw_audio
.buffer_size
> 0 &&
424 fFormat
.u
.raw_audio
.frame_rate
> 0 &&
426 duration
= (bigtime_t
)(((fFormat
.u
.raw_audio
.buffer_size
/ sample_size
) /
427 fFormat
.u
.raw_audio
.frame_rate
) * 1000000.0);
430 SetBufferDuration(duration
);
434 VSTNode::Disconnect(const media_source
&src
, const media_destination
&dst
)
436 if (src
!= fOutputMedia
.source
)
439 if (dst
!= fOutputMedia
.destination
)
442 fOutputMedia
.destination
= media_destination::null
;
444 if (fInputMedia
.source
== media_source::null
)
445 fFormat
.u
.raw_audio
= media_raw_audio_format::wildcard
;
447 fOutputMedia
.format
= fFormat
;
451 VSTNode::EnableOutput(const media_source
&src
, bool enabled
, int32
* _deprecated_
)
453 if (src
!= fOutputMedia
.source
)
456 fOutputMediaEnabled
= enabled
;
460 VSTNode::GetLatency(bigtime_t
* latency
)
462 *latency
= EventLatency() + SchedulingLatency();
467 VSTNode::LatencyChanged(const media_source
&src
, const media_destination
&dst
,
468 bigtime_t latency
, uint32 flags
)
470 if (src
!= fOutputMedia
.source
|| dst
!= fOutputMedia
.destination
)
473 fDownstreamLatency
= latency
;
474 SetEventLatency(fDownstreamLatency
+ fProcessLatency
);
476 if (fInputMedia
.source
!= media_source::null
) {
477 SendLatencyChange(fInputMedia
.source
,
478 fInputMedia
.destination
,EventLatency() + SchedulingLatency());
484 VSTNode::OfflineTime()
491 VSTNode::HandleEvent(const media_timed_event
*event
, bigtime_t late
,
494 if(event
->type
== BTimedEventQueue::B_PARAMETER
)
495 ParameterEventProcessing(event
);
499 VSTNode::ParameterEventProcessing(const media_timed_event
* event
)
504 int32 id
= event
->bigdata
;
505 size_t size
= event
->data
;
506 bigtime_t now
= TimeSource()->Now();
508 type_code v_type
= B_FLOAT_TYPE
;
510 BParameter
* web_param
;
511 for(int i
= 0; i
< fWeb
->CountParameters(); i
++) {
512 web_param
= fWeb
->ParameterAt(i
);
513 if(web_param
->ID() == id
) {
514 v_type
= web_param
->ValueType();
519 if (v_type
== B_FLOAT_TYPE
)
520 value
= *((float*)event
->pointer
);
521 if (v_type
== B_INT32_TYPE
) {
522 value32
= *((int32
*)event
->pointer
);
523 value
= (float)value32
;
528 fMuteLastChanged
= now
;
529 BroadcastNewParameterValue(now
, id
, event
->pointer
, size
);
530 } else if (id
== P_BYPASS
) {
532 fByPassLastChanged
= now
;
533 BroadcastNewParameterValue(now
, id
, event
->pointer
, size
);
535 int32 idx
= id
- P_PARAM
;
536 if (idx
>= 0 && idx
< fPlugin
->ParametersCount()) {
537 VSTParameter
*param
= fPlugin
->Parameter(idx
);
538 param
->SetValue(value
);
539 BroadcastNewParameterValue(now
, id
, &value
, size
);
545 VSTNode::ValidateFormat(const media_format
&preferredFormat
,
546 media_format
&proposedFormat
)
550 if (proposedFormat
.type
!= B_MEDIA_RAW_AUDIO
) {
551 proposedFormat
= preferredFormat
;
552 return B_MEDIA_BAD_FORMAT
;
555 media_raw_audio_format
&wild
= media_raw_audio_format::wildcard
;
556 media_raw_audio_format
&f
= proposedFormat
.u
.raw_audio
;
557 const media_raw_audio_format
&pref
= preferredFormat
.u
.raw_audio
;
559 if(pref
.frame_rate
!= wild
.frame_rate
&& f
.frame_rate
!= pref
.frame_rate
) {
560 if(f
.frame_rate
!= wild
.frame_rate
)
561 ret
= B_MEDIA_BAD_FORMAT
;
562 f
.frame_rate
= pref
.frame_rate
;
565 if(pref
.channel_count
!= wild
.channel_count
&&
566 f
.channel_count
!= pref
.channel_count
) {
567 if(f
.channel_count
!= wild
.channel_count
)
568 ret
= B_MEDIA_BAD_FORMAT
;
569 f
.channel_count
= pref
.channel_count
;
572 if(pref
.format
!= wild
.format
&& f
.format
!= pref
.format
) {
573 if(f
.format
!= wild
.format
)
574 ret
= B_MEDIA_BAD_FORMAT
;
575 f
.format
= pref
.format
;
578 if(pref
.byte_order
!= wild
.byte_order
&&
579 f
.byte_order
!= pref
.byte_order
) {
580 if(f
.byte_order
!= wild
.byte_order
)
581 ret
= B_MEDIA_BAD_FORMAT
;
582 f
.byte_order
= pref
.byte_order
;
585 if(pref
.buffer_size
!= wild
.buffer_size
&&
586 f
.buffer_size
!= pref
.buffer_size
) {
587 if(f
.buffer_size
!= wild
.buffer_size
)
588 ret
= B_MEDIA_BAD_FORMAT
;
589 f
.buffer_size
= pref
.buffer_size
;
597 VSTNode::SetOutputFormat(media_format
&format
)
599 media_raw_audio_format
&f
= format
.u
.raw_audio
;
600 media_raw_audio_format
&w
= media_raw_audio_format::wildcard
;
602 if (f
.frame_rate
== w
.frame_rate
)
603 f
.frame_rate
= 44100.0;
605 if (f
.channel_count
== w
.channel_count
) {
606 if(fInputMedia
.source
!= media_source::null
)
607 f
.channel_count
= fInputMedia
.format
.u
.raw_audio
.channel_count
;
609 f
.channel_count
= fPlugin
->Channels(VST_OUTPUT_CHANNELS
);
612 if (f
.format
== w
.format
)
613 f
.format
= media_raw_audio_format::B_AUDIO_FLOAT
;
615 if (f
.byte_order
== w
.format
) {
616 f
.byte_order
= (B_HOST_IS_BENDIAN
) ?
617 B_MEDIA_BIG_ENDIAN
: B_MEDIA_LITTLE_ENDIAN
;
620 if (f
.buffer_size
== w
.buffer_size
)
621 f
.buffer_size
= BUFF_SIZE
;
625 VSTNode::InitParameterValues()
629 fMuteLastChanged
= 0LL;
630 fByPassLastChanged
= 0LL;
634 VSTNode::InitParameterWeb()
636 fWeb
= new BParameterWeb();
638 bool switch_group_needed
= false;
639 for(int i
= 0; i
< fPlugin
->ParametersCount(); i
++) {
640 VSTParameter
* param
= fPlugin
->Parameter(i
);
641 if (param
->Type() == VST_PARAM_CHECKBOX
||
642 param
->Type() == VST_PARAM_DROPLIST
) {
643 switch_group_needed
= true;
648 BParameterGroup
* fParamGroup
= fWeb
->MakeGroup("Parameters");
649 BParameterGroup
* fSwitchesGroup
= switch_group_needed
?
650 fWeb
->MakeGroup("Switches") : NULL
;
651 BParameterGroup
* fAboutGroup
= fWeb
->MakeGroup("About");
654 BNullParameter
* label
;
655 BParameterGroup
* group
;
657 BParameterGroup
* fFControlGroup
= fParamGroup
->MakeGroup("FilterControl");
658 BParameterGroup
* fCheckBoxGroup
= switch_group_needed
?
659 fSwitchesGroup
->MakeGroup("CheckBoxes") : NULL
;
660 BParameterGroup
* fSelectorsGroup
= switch_group_needed
?
661 fSwitchesGroup
->MakeGroup("Selectors") : NULL
;
663 fFControlGroup
->MakeDiscreteParameter(P_MUTE
,
664 B_MEDIA_NO_TYPE
,"Mute", B_ENABLE
);
665 fFControlGroup
->MakeDiscreteParameter(P_BYPASS
,
666 B_MEDIA_NO_TYPE
,"ByPass", B_ENABLE
);
668 for(int i
= 0; i
< fPlugin
->ParametersCount(); i
++) {
669 VSTParameter
*param
= fPlugin
->Parameter(i
);
670 switch(param
->Type()) {
671 case VST_PARAM_CHECKBOX
:
674 str
<< param
->Name() << " (" << param
->MinimumValue()
675 << "/" << param
->MaximumValue() << ")";
676 value
= fCheckBoxGroup
->MakeDiscreteParameter(
677 P_PARAM
+ param
->Index(), B_MEDIA_NO_TYPE
,
678 str
.String(), B_ENABLE
);
681 case VST_PARAM_DROPLIST
:
683 BDiscreteParameter
*dvalue
=
684 fSelectorsGroup
->MakeDiscreteParameter(P_PARAM
+ param
->Index(),
685 B_MEDIA_NO_TYPE
, param
->Name(), B_OUTPUT_MUX
);
686 for(int j
= 0; j
< param
->ListCount(); j
++) {
687 dvalue
->AddItem( param
->ListItemAt(j
)->Index
,
688 param
->ListItemAt(j
)->Name
.String());
696 group
= fParamGroup
->MakeGroup(param
->Name());
697 label
= group
->MakeNullParameter(P_LABEL
+ param
->Index(),
698 B_MEDIA_NO_TYPE
, param
->Name(), B_GENERIC
);
700 str
.SetTo(param
->MaximumValue());
701 str
<< " " << param
->Unit();
703 group
->MakeNullParameter(P_LABEL2
+ param
->Index(),
704 B_MEDIA_NO_TYPE
, str
.String(), B_GENERIC
);
705 value
= group
->MakeContinuousParameter(P_PARAM
+ param
->Index(),
706 B_MEDIA_NO_TYPE
, "", B_GAIN
, "", 0.0, 1.0, 0.01);
707 label
->AddOutput(value
);
708 value
->AddInput(label
);
710 str
.SetTo(param
->MinimumValue());
711 str
<< " " << param
->Unit();
713 group
->MakeNullParameter(P_LABEL3
+ param
->Index(),
714 B_MEDIA_NO_TYPE
, str
.String(), B_GENERIC
);
720 BString
str("About plugin");
721 label
= fAboutGroup
->MakeNullParameter(P_ABOUT
+ 0,
722 B_MEDIA_NO_TYPE
, str
.String(), B_GENERIC
);
724 str
.SetTo("Effect name: ");
725 if (strlen(fPlugin
->EffectName()) != 0)
726 str
.Append(fPlugin
->EffectName());
728 str
.Append("not specified");
730 label
= fAboutGroup
->MakeNullParameter(P_ABOUT
+ 1,
731 B_MEDIA_NO_TYPE
, str
.String(), B_GENERIC
);
733 str
.SetTo("Vendor: ");
734 if (strlen(fPlugin
->Vendor()) != 0)
735 str
.Append(fPlugin
->Vendor());
737 str
.Append("not specified");
739 label
= fAboutGroup
->MakeNullParameter(P_ABOUT
+ 2,
740 B_MEDIA_NO_TYPE
, str
.String(), B_GENERIC
);
742 str
.SetTo("Product: ");
743 if (strlen(fPlugin
->Product()) != 0)
744 str
.Append(fPlugin
->Product());
746 str
.Append("not specified");
748 label
= fAboutGroup
->MakeNullParameter(P_ABOUT
+ 3,
749 B_MEDIA_NO_TYPE
, str
.String(), B_GENERIC
);
751 str
.SetTo("Input Channels: ");
752 str
<<fPlugin
->Channels(VST_INPUT_CHANNELS
);
753 label
= fAboutGroup
->MakeNullParameter(P_ABOUT
+ 4,
754 B_MEDIA_NO_TYPE
, str
.String(), B_GENERIC
);
756 str
.SetTo("Output Channels: ");
757 str
<<fPlugin
->Channels(VST_OUTPUT_CHANNELS
);
758 label
= fAboutGroup
->MakeNullParameter(P_ABOUT
+ 5,
759 B_MEDIA_NO_TYPE
, str
.String(), B_GENERIC
);
761 SetParameterWeb(fWeb
);
765 VSTNode::InitFilter()
767 fBlockSize
= fFormat
.u
.raw_audio
.buffer_size
/
768 (fFormat
.u
.raw_audio
.channel_count
* sizeof(float));
770 fPlugin
->SetBlockSize(fBlockSize
);
771 fPlugin
->SetSampleRate(fFormat
.u
.raw_audio
.frame_rate
);
775 VSTNode::GetFilterLatency()
777 if (fOutputMedia
.destination
== media_destination::null
)
780 BBufferGroup
* temp_group
=
781 new BBufferGroup(fOutputMedia
.format
.u
.raw_audio
.buffer_size
, 1);
784 temp_group
->RequestBuffer(fOutputMedia
.format
.u
.raw_audio
.buffer_size
);
785 buffer
->Header()->type
= B_MEDIA_RAW_AUDIO
;
786 buffer
->Header()->size_used
= fOutputMedia
.format
.u
.raw_audio
.buffer_size
;
788 bigtime_t begin
= system_time();
789 FilterBuffer(buffer
);
790 bigtime_t latency
= system_time()-begin
;
801 VSTNode::FilterBuffer(BBuffer
* buffer
)
803 uint32 m_frameSize
= (fFormat
.u
.raw_audio
.format
& 0x0f)*
804 fFormat
.u
.raw_audio
.channel_count
;
805 uint32 samples
= buffer
->Header()->size_used
/ m_frameSize
;
806 uint32 channels
= fFormat
.u
.raw_audio
.channel_count
;
809 memset(buffer
->Data(), 0, buffer
->Header()->size_used
);
812 fPlugin
->Process((float*)buffer
->Data(), samples
, channels
);