1 /*
2 * Copyright 2012, Gerasim Troeglazov (3dEyes**), 3dEyes@gmail.com.
3 * All rights reserved.
4 * Distributed under the terms of the MIT License.
5 */
6
7 #include <ByteOrder.h>
8 #include <Buffer.h>
9 #include <BufferGroup.h>
10 #include <TimeSource.h>
11 #include <ParameterWeb.h>
12 #include <String.h>
13
14 #include <stdio.h>
15 #include <string.h>
16
17 #include "EqualizerNode.h"
18
19 //EqualizerNode
~EqualizerNode()20 EqualizerNode::~EqualizerNode()
21 {
22 Quit();
23 }
24
25
EqualizerNode(BMediaAddOn * addon)26 EqualizerNode::EqualizerNode(BMediaAddOn* addon)
27 :
28 BMediaNode("10 Band Equalizer"),
29 BBufferConsumer(B_MEDIA_RAW_AUDIO),
30 BBufferProducer(B_MEDIA_RAW_AUDIO),
31 BControllable(),
32 BMediaEventLooper(),
33 fAddOn(addon),
34 fProcessLatency(0),
35 fDownstreamLatency(0),
36 fOutputMediaEnabled(true)
37 {
38 }
39
40
41 //BMediaNode
42 BMediaAddOn*
AddOn(int32 * id) const43 EqualizerNode::AddOn(int32* id) const
44 {
45 if (fAddOn)
46 *id = 0;
47 return fAddOn;
48 }
49
50
51 status_t
HandleMessage(int32 message,const void * data,size_t size)52 EqualizerNode::HandleMessage(int32 message, const void *data, size_t size)
53 {
54 if ((BControllable::HandleMessage(message, data, size) != B_OK) &&
55 (BBufferConsumer::HandleMessage(message, data, size) != B_OK) &&
56 (BBufferProducer::HandleMessage(message, data, size) != B_OK) &&
57 (BControllable::HandleMessage(message, data, size) != B_OK)) {
58 BMediaNode::HandleMessage(message, data, size);
59 return B_OK;
60 }
61 BMediaNode::HandleBadMessage(message, data, size);
62 return B_ERROR;
63 }
64
65
66 void
NodeRegistered()67 EqualizerNode::NodeRegistered()
68 {
69 fPreferredFormat.type = B_MEDIA_RAW_AUDIO;
70 fPreferredFormat.u.raw_audio.buffer_size = BUFF_SIZE;
71 fPreferredFormat.u.raw_audio = media_raw_audio_format::wildcard;
72 fPreferredFormat.u.raw_audio.channel_count =
73 media_raw_audio_format::wildcard.channel_count;
74 fPreferredFormat.u.raw_audio.format = media_raw_audio_format::B_AUDIO_FLOAT;
75
76 fFormat.type = B_MEDIA_RAW_AUDIO;
77 fFormat.u.raw_audio = media_raw_audio_format::wildcard;
78
79 fInputMedia.destination.port = ControlPort();
80 fInputMedia.destination.id = ID_AUDIO_INPUT;
81 fInputMedia.node = Node();
82 fInputMedia.source = media_source::null;
83 fInputMedia.format = fFormat;
84 strncpy(fInputMedia.name, "Audio Input", B_MEDIA_NAME_LENGTH);
85
86 fOutputMedia.source.port = ControlPort();
87 fOutputMedia.source.id = ID_AUDIO_OUTPUT;
88 fOutputMedia.node = Node();
89 fOutputMedia.destination = media_destination::null;
90 fOutputMedia.format = fFormat;
91 strncpy(fOutputMedia.name, "Audio Output", B_MEDIA_NAME_LENGTH);
92
93 InitParameterValues();
94 InitParameterWeb();
95
96 SetPriority(B_REAL_TIME_PRIORITY);
97 Run();
98 }
99
100
101 //BControllable
102 status_t
GetParameterValue(int32 id,bigtime_t * lastChangeTime,void * value,size_t * size)103 EqualizerNode::GetParameterValue(int32 id, bigtime_t* lastChangeTime,
104 void* value, size_t* size)
105 {
106 if (*size < sizeof(float))
107 return B_NO_MEMORY;
108
109 if (id == P_MUTE) {
110 *(int32*)value = fMute;
111 *lastChangeTime = fMuteLastChanged;
112 *size = sizeof(int32);
113 } else if (id == P_BYPASS) {
114 *(int32*)value = fByPass;
115 *lastChangeTime = fByPassLastChanged;
116 *size = sizeof(int32);
117 } else if (id == P_PREAMP) {
118 *(float*)value = (float)fEqualizer.PreAmp();
119 *lastChangeTime = fPreAmpLastChanged;
120 *size = sizeof(float);
121 } else if (id >= P_BANDS && id < P_BANDS + fEqualizer.BandCount()) {
122 int band = id - P_BANDS;
123 *(float*)value = (float)fEqualizer.Band(band);
124 *lastChangeTime = fBandsLastChanged[band];
125 *size = sizeof(float);
126 } else
127 return B_ERROR;
128 return B_OK;
129 }
130
131
132 void
SetParameterValue(int32 id,bigtime_t time,const void * value,size_t size)133 EqualizerNode::SetParameterValue(int32 id, bigtime_t time, const void* value,
134 size_t size)
135 {
136 if (id == P_PREAMP || id == P_BYPASS || id == P_MUTE
137 || (id >= P_BANDS && id < P_BANDS + fEqualizer.BandCount())) {
138 media_timed_event ev(time, BTimedEventQueue::B_PARAMETER, (void*)value,
139 BTimedEventQueue::B_NO_CLEANUP, size, id, (char*)"EQ");
140 //dirty hack for parameter processing (mediakit bug????)
141 ParameterEventProcessing(&ev);
142 EventQueue()->AddEvent(ev);
143 }
144 }
145
146
147 //BBufferConsumer
148 void
BufferReceived(BBuffer * buffer)149 EqualizerNode::BufferReceived(BBuffer* buffer)
150 {
151 if (buffer->Header()->destination != fInputMedia.destination.id) {
152 buffer->Recycle();
153 return;
154 }
155
156 if (fOutputMedia.destination == media_destination::null
157 || !fOutputMediaEnabled) {
158 buffer->Recycle();
159 return;
160 }
161
162 FilterBuffer(buffer);
163
164 status_t err = SendBuffer(buffer, fOutputMedia.source,
165 fOutputMedia.destination);
166 if (err < B_OK)
167 buffer->Recycle();
168 }
169
170
171 status_t
AcceptFormat(const media_destination & dst,media_format * format)172 EqualizerNode::AcceptFormat(const media_destination &dst, media_format* format)
173 {
174 if (dst != fInputMedia.destination)
175 return B_MEDIA_BAD_DESTINATION;
176
177 if (format->type != B_MEDIA_RAW_AUDIO)
178 return B_MEDIA_BAD_FORMAT;
179
180 ValidateFormat((fFormat.u.raw_audio.format
181 != media_raw_audio_format::wildcard.format) ?
182 fFormat : fPreferredFormat, *format);
183
184 return B_OK;
185 }
186
187
188 status_t
GetNextInput(int32 * cookie,media_input * input)189 EqualizerNode::GetNextInput(int32* cookie, media_input* input)
190 {
191 if (*cookie)
192 return B_BAD_INDEX;
193
194 ++*cookie;
195 *input = fInputMedia;
196 return B_OK;
197 }
198
199
200 void
DisposeInputCookie(int32 cookie)201 EqualizerNode::DisposeInputCookie(int32 cookie)
202 {
203 }
204
205
206 status_t
FormatChanged(const media_source & src,const media_destination & dst,int32 changeTag,const media_format & format)207 EqualizerNode::FormatChanged(const media_source &src,
208 const media_destination &dst, int32 changeTag, const media_format &format)
209 {
210 return B_MEDIA_BAD_FORMAT;
211 }
212
213
214 void
ProducerDataStatus(const media_destination & dst,int32 status,bigtime_t when)215 EqualizerNode::ProducerDataStatus(const media_destination &dst, int32 status,
216 bigtime_t when)
217 {
218 if (fOutputMedia.destination != media_destination::null)
219 SendDataStatus(status, fOutputMedia.destination, when);
220 }
221
222
223 status_t
GetLatencyFor(const media_destination & dst,bigtime_t * latency,media_node_id * outTimeSource)224 EqualizerNode::GetLatencyFor(const media_destination &dst, bigtime_t* latency,
225 media_node_id* outTimeSource)
226 {
227
228 if (dst != fInputMedia.destination)
229 return B_MEDIA_BAD_DESTINATION;
230
231 *latency = fDownstreamLatency + fProcessLatency;
232 *outTimeSource = TimeSource()->ID();
233 return B_OK;
234 }
235
236
237 status_t
Connected(const media_source & source,const media_destination & destination,const media_format & format,media_input * poInput)238 EqualizerNode::Connected(const media_source& source,
239 const media_destination& destination, const media_format& format,
240 media_input* poInput)
241 {
242 if (destination != fInputMedia.destination)
243 return B_MEDIA_BAD_DESTINATION;
244
245 if (fInputMedia.source != media_source::null)
246 return B_MEDIA_ALREADY_CONNECTED;
247
248 fInputMedia.source = source;
249 fInputMedia.format = format;
250 *poInput = fInputMedia;
251 fFormat = format;
252
253 return B_OK;
254 }
255
256
257 void
Disconnected(const media_source & src,const media_destination & dst)258 EqualizerNode::Disconnected(const media_source &src,
259 const media_destination &dst)
260 {
261 if (fInputMedia.source != src || dst != fInputMedia.destination)
262 return;
263
264 fInputMedia.source = media_source::null;
265
266 if (fOutputMedia.destination == media_destination::null)
267 fFormat.u.raw_audio = media_raw_audio_format::wildcard;
268
269 fInputMedia.format = fFormat;
270 }
271
272
273 //BBufferProducer
274 status_t
FormatSuggestionRequested(media_type type,int32 quality,media_format * format)275 EqualizerNode::FormatSuggestionRequested(media_type type, int32 quality,
276 media_format* format)
277 {
278 if (type != B_MEDIA_RAW_AUDIO)
279 return B_MEDIA_BAD_FORMAT;
280
281 if (fFormat.u.raw_audio.format != media_raw_audio_format::wildcard.format)
282 *format = fFormat;
283 else
284 *format = fPreferredFormat;
285 return B_OK;
286 }
287
288
289 status_t
FormatProposal(const media_source & src,media_format * format)290 EqualizerNode::FormatProposal(const media_source &src, media_format* format)
291 {
292 if (src != fOutputMedia.source)
293 return B_MEDIA_BAD_SOURCE;
294
295 if (format->type != B_MEDIA_RAW_AUDIO)
296 return B_MEDIA_BAD_FORMAT;
297
298 ValidateFormat((fFormat.u.raw_audio.format
299 != media_raw_audio_format::wildcard.format) ?
300 fFormat:fPreferredFormat, *format);
301
302 return B_OK;
303 }
304
305
306 status_t
FormatChangeRequested(const media_source & src,const media_destination & dst,media_format * format,int32 * _deprecated_)307 EqualizerNode::FormatChangeRequested(const media_source &src,
308 const media_destination &dst, media_format* format, int32* _deprecated_)
309 {
310 return B_MEDIA_BAD_FORMAT;
311 }
312
313
314 void
LateNoticeReceived(const media_source & src,bigtime_t late,bigtime_t when)315 EqualizerNode::LateNoticeReceived(const media_source &src, bigtime_t late,
316 bigtime_t when)
317 {
318 if (src != fOutputMedia.source || fInputMedia.source == media_source::null)
319 return;
320
321 NotifyLateProducer(fInputMedia.source, late, when);
322 }
323
324
325 status_t
GetNextOutput(int32 * cookie,media_output * output)326 EqualizerNode::GetNextOutput(int32* cookie, media_output* output)
327 {
328 if (*cookie)
329 return B_BAD_INDEX;
330
331 ++*cookie;
332 *output = fOutputMedia;
333 return B_OK;
334 }
335
336
337 status_t
DisposeOutputCookie(int32 cookie)338 EqualizerNode::DisposeOutputCookie(int32 cookie)
339 {
340 return B_OK;
341 }
342
343
344 status_t
SetBufferGroup(const media_source & src,BBufferGroup * group)345 EqualizerNode::SetBufferGroup(const media_source &src, BBufferGroup* group)
346 {
347 int32 changeTag;
348 status_t ret = B_OK;
349
350 if (src != fOutputMedia.source)
351 return B_MEDIA_BAD_SOURCE;
352
353 if (fInputMedia.source == media_source::null)
354 return B_ERROR;
355
356 ret = SetOutputBuffersFor(fInputMedia.source, fInputMedia.destination,
357 group, 0, &changeTag);
358 return ret;
359 }
360
361
362 status_t
PrepareToConnect(const media_source & src,const media_destination & dst,media_format * format,media_source * outSource,char * outName)363 EqualizerNode::PrepareToConnect(const media_source &src,
364 const media_destination &dst, media_format* format, media_source* outSource,
365 char* outName)
366 {
367 if (src != fOutputMedia.source)
368 return B_MEDIA_BAD_SOURCE;
369
370 if (format->type != B_MEDIA_RAW_AUDIO)
371 return B_MEDIA_BAD_FORMAT;
372
373 if (fOutputMedia.destination != media_destination::null)
374 return B_MEDIA_ALREADY_CONNECTED;
375
376 status_t err = ValidateFormat((fFormat.u.raw_audio.format
377 != media_raw_audio_format::wildcard.format) ? fFormat
378 : fPreferredFormat, *format);
379
380 if (err < B_OK)
381 return err;
382
383 SetOutputFormat(*format);
384
385 fOutputMedia.destination = dst;
386 fOutputMedia.format = *format;
387
388 *outSource = fOutputMedia.source;
389 strncpy(outName, fOutputMedia.name, B_MEDIA_NAME_LENGTH);
390
391 return B_OK;
392 }
393
394
395 void
Connect(status_t status,const media_source & src,const media_destination & dst,const media_format & format,char * name)396 EqualizerNode::Connect(status_t status, const media_source &src,
397 const media_destination &dst, const media_format &format, char* name)
398 {
399 if (status < B_OK) {
400 fOutputMedia.destination = media_destination::null;
401 return;
402 }
403
404 strncpy(name, fOutputMedia.name, B_MEDIA_NAME_LENGTH);
405 fOutputMedia.destination = dst;
406 fFormat = format;
407
408 media_node_id timeSource;
409 FindLatencyFor(fOutputMedia.destination, &fDownstreamLatency, &timeSource);
410
411 InitFilter();
412
413 fProcessLatency = GetFilterLatency();
414 SetEventLatency(fDownstreamLatency + fProcessLatency);
415
416 if (fInputMedia.source != media_source::null) {
417 SendLatencyChange(fInputMedia.source, fInputMedia.destination,
418 EventLatency() + SchedulingLatency());
419 }
420
421 bigtime_t duration = 0;
422
423 int sample_size = (fFormat.u.raw_audio.format & 0xf)
424 * fFormat.u.raw_audio.channel_count;
425
426 if (fFormat.u.raw_audio.buffer_size > 0
427 && fFormat.u.raw_audio.frame_rate > 0 && sample_size > 0) {
428 duration = (bigtime_t)(((fFormat.u.raw_audio.buffer_size / sample_size)
429 / fFormat.u.raw_audio.frame_rate) * 1000000.0);
430 }
431
432 SetBufferDuration(duration);
433 }
434
435
436 void
Disconnect(const media_source & src,const media_destination & dst)437 EqualizerNode::Disconnect(const media_source &src, const media_destination &dst)
438 {
439 if (src != fOutputMedia.source)
440 return;
441
442 if (dst != fOutputMedia.destination)
443 return;
444
445 fOutputMedia.destination = media_destination::null;
446
447 if (fInputMedia.source == media_source::null)
448 fFormat.u.raw_audio = media_raw_audio_format::wildcard;
449
450 fOutputMedia.format = fFormat;
451 }
452
453
454 void
EnableOutput(const media_source & src,bool enabled,int32 * _deprecated_)455 EqualizerNode::EnableOutput(const media_source &src, bool enabled,
456 int32* _deprecated_)
457 {
458 if (src != fOutputMedia.source)
459 return;
460 fOutputMediaEnabled = enabled;
461 }
462
463
464 status_t
GetLatency(bigtime_t * latency)465 EqualizerNode::GetLatency(bigtime_t* latency)
466 {
467 *latency = EventLatency() + SchedulingLatency();
468 return B_OK;
469 }
470
471
472 void
LatencyChanged(const media_source & src,const media_destination & dst,bigtime_t latency,uint32 flags)473 EqualizerNode::LatencyChanged(const media_source &src,
474 const media_destination &dst, bigtime_t latency, uint32 flags)
475 {
476 if (src != fOutputMedia.source || dst != fOutputMedia.destination)
477 return;
478
479 fDownstreamLatency = latency;
480 SetEventLatency(fDownstreamLatency + fProcessLatency);
481
482 if (fInputMedia.source != media_source::null) {
483 SendLatencyChange(fInputMedia.source,
484 fInputMedia.destination,EventLatency() + SchedulingLatency());
485 }
486 }
487
488
489 //BMediaEventLooper
490 bigtime_t
OfflineTime()491 EqualizerNode::OfflineTime()
492 {
493 return 0LL;
494 }
495
496
497 //EqualizerNode
498 void
HandleEvent(const media_timed_event * event,bigtime_t late,bool realTime)499 EqualizerNode::HandleEvent(const media_timed_event* event, bigtime_t late,
500 bool realTime)
501 {
502 if (event->type == BTimedEventQueue::B_PARAMETER)
503 ParameterEventProcessing(event);
504 }
505
506
507 void
ParameterEventProcessing(const media_timed_event * event)508 EqualizerNode::ParameterEventProcessing(const media_timed_event* event)
509 {
510 float value = 0.0;
511 int32 value32 = 0;
512
513 int32 id = event->bigdata;
514 size_t size = event->data;
515 bigtime_t now = TimeSource()->Now();
516
517 type_code v_type = B_FLOAT_TYPE;
518
519 BParameter* web_param;
520
521 for (int i = 0; i < fWeb->CountParameters(); i++) {
522 web_param = fWeb->ParameterAt(i);
523 if (web_param->ID() == id) {
524 v_type=web_param->ValueType();
525 break;
526 }
527 }
528
529 if (v_type == B_FLOAT_TYPE)
530 value = *((float*)event->pointer);
531 else if (v_type == B_INT32_TYPE) {
532 value32 = *((int32*)event->pointer);
533 value = (float)value32;
534 }
535
536 if (id == P_MUTE) {
537 fMute = value32;
538 fMuteLastChanged = now;
539 BroadcastNewParameterValue(now, id, event->pointer, size);
540 } else if (id == P_BYPASS) {
541 fByPass = value32;
542 fByPassLastChanged = now;
543 BroadcastNewParameterValue(now, id, event->pointer, size);
544 } else if (id == P_PREAMP) {
545 if (value != fEqualizer.PreAmp()) {
546 fEqualizer.SetPreAmp(value);
547 fPreAmpLastChanged = now;
548 BroadcastNewParameterValue(now, id, &value, size);
549 }
550 } else if (id >= P_BANDS && id < P_BANDS + fEqualizer.BandCount()) {
551 int band = id - P_BANDS;
552 if (value != fEqualizer.Band(band)) {
553 fEqualizer.SetBand(band, value);
554 fBandsLastChanged[band] = now;
555 BroadcastNewParameterValue(now, id, &value, size);
556 }
557 }
558 }
559
560
561 status_t
ValidateFormat(const media_format & preferred_format,media_format & proposed_format)562 EqualizerNode::ValidateFormat(const media_format &preferred_format,
563 media_format &proposed_format)
564 {
565 status_t ret = B_OK;
566
567 if (proposed_format.type != B_MEDIA_RAW_AUDIO) {
568 proposed_format = preferred_format;
569 return B_MEDIA_BAD_FORMAT;
570 }
571
572 const media_raw_audio_format &wild = media_raw_audio_format::wildcard;
573 media_raw_audio_format &f = proposed_format.u.raw_audio;
574 const media_raw_audio_format &pref = preferred_format.u.raw_audio;
575
576 if(pref.frame_rate != wild.frame_rate && f.frame_rate != pref.frame_rate) {
577 if(f.frame_rate != wild.frame_rate)
578 ret = B_MEDIA_BAD_FORMAT;
579 f.frame_rate = pref.frame_rate;
580 }
581
582 if(pref.channel_count != wild.channel_count &&
583 f.channel_count != pref.channel_count) {
584 if(f.channel_count != wild.channel_count)
585 ret = B_MEDIA_BAD_FORMAT;
586 f.channel_count = pref.channel_count;
587 }
588
589 if(pref.format != wild.format && f.format != pref.format) {
590 if(f.format != wild.format)
591 ret = B_MEDIA_BAD_FORMAT;
592 f.format = pref.format;
593 }
594
595 if(pref.byte_order != wild.byte_order &&
596 f.byte_order != pref.byte_order) {
597 if(f.byte_order != wild.byte_order)
598 ret = B_MEDIA_BAD_FORMAT;
599 f.byte_order = pref.byte_order;
600 }
601
602 if(pref.buffer_size != wild.buffer_size &&
603 f.buffer_size != pref.buffer_size) {
604 if(f.buffer_size != wild.buffer_size)
605 ret = B_MEDIA_BAD_FORMAT;
606 f.buffer_size = pref.buffer_size;
607 }
608
609 return ret;
610 }
611
612
613 void
SetOutputFormat(media_format & format)614 EqualizerNode::SetOutputFormat(media_format &format)
615 {
616 media_raw_audio_format &f = format.u.raw_audio;
617 const media_raw_audio_format &w = media_raw_audio_format::wildcard;
618
619 if (f.frame_rate == w.frame_rate) {
620 f.frame_rate = 44100.0;
621 }
622 if (f.channel_count == w.channel_count) {
623 if(fInputMedia.source != media_source::null)
624 f.channel_count = fInputMedia.format.u.raw_audio.channel_count;
625 else
626 f.channel_count = 2;
627 }
628
629 if (f.format == w.format)
630 f.format = media_raw_audio_format::B_AUDIO_FLOAT;
631
632 if (f.byte_order == w.format) {
633 f.byte_order = (B_HOST_IS_BENDIAN) ?
634 B_MEDIA_BIG_ENDIAN : B_MEDIA_LITTLE_ENDIAN;
635 }
636
637 if (f.buffer_size == w.buffer_size)
638 f.buffer_size = BUFF_SIZE;
639 }
640
641
642 void
InitParameterValues()643 EqualizerNode::InitParameterValues()
644 {
645 fMute = 0;
646 fByPass = 0;
647 fMuteLastChanged = 0LL;
648 fByPassLastChanged = 0LL;
649 fPreAmpLastChanged = 0LL;
650
651 for (int i = 0; i < EQ_BANDS; i++)
652 fBandsLastChanged[i] = 0LL;
653
654 fEqualizer.CleanUp();
655 }
656
657
658 void
InitParameterWeb(void)659 EqualizerNode::InitParameterWeb(void)
660 {
661 fWeb = new BParameterWeb();
662
663 BParameterGroup* fParamGroup = fWeb->MakeGroup("EqualizerNode Parameters");
664 BParameterGroup* fFControlGroup = fParamGroup->MakeGroup("FilterControl");
665
666 fFControlGroup->MakeDiscreteParameter(P_MUTE,B_MEDIA_NO_TYPE,"Mute",
667 B_ENABLE);
668 fFControlGroup->MakeDiscreteParameter(P_BYPASS,B_MEDIA_NO_TYPE,"ByPass",
669 B_ENABLE);
670
671 BNullParameter* label;
672 BParameterGroup* group;
673 BContinuousParameter* value;
674
675 group = fParamGroup->MakeGroup("Pre Amp");
676 label = group->MakeNullParameter(P_PREAMP_LABEL, B_MEDIA_NO_TYPE, "Pre Amp",
677 B_GENERIC);
678 value = group->MakeContinuousParameter(P_PREAMP, B_MEDIA_NO_TYPE, "",
679 B_GAIN, "dB", -8.0, 8.0, 0.1);
680 label->AddOutput(value);
681 value->AddInput(label);
682
683 for (int i = 0; i < fEqualizer.BandCount(); i++) {
684 char freq[32];
685 sprintf(freq,"%gHz",fEqualizer.BandFrequency(i));
686 group = fParamGroup->MakeGroup(freq);
687 label = group->MakeNullParameter(P_BAND_LABELS + i, B_MEDIA_NO_TYPE,
688 freq, B_GENERIC);
689 value = group->MakeContinuousParameter(P_BANDS + i, B_MEDIA_NO_TYPE,
690 "", B_GAIN, "dB", -16.0, 16.0, 0.1);
691 label->AddOutput(value);
692 value->AddInput(label);
693 }
694
695 SetParameterWeb(fWeb);
696 }
697
698
699 void
InitFilter(void)700 EqualizerNode::InitFilter(void)
701 {
702 fEqualizer.SetFormat(fFormat.u.raw_audio.channel_count,
703 fFormat.u.raw_audio.frame_rate);
704 }
705
706
707 bigtime_t
GetFilterLatency(void)708 EqualizerNode::GetFilterLatency(void)
709 {
710 if (fOutputMedia.destination == media_destination::null)
711 return 0LL;
712
713 BBufferGroup* test_group =
714 new BBufferGroup(fOutputMedia.format.u.raw_audio.buffer_size, 1);
715
716 BBuffer* buffer =
717 test_group->RequestBuffer(fOutputMedia.format.u.raw_audio.buffer_size);
718 buffer->Header()->type = B_MEDIA_RAW_AUDIO;
719 buffer->Header()->size_used = fOutputMedia.format.u.raw_audio.buffer_size;
720
721 bigtime_t begin = system_time();
722 FilterBuffer(buffer);
723 bigtime_t latency = system_time() - begin;
724
725 buffer->Recycle();
726 delete test_group;
727
728 InitFilter();
729
730 return latency;
731 }
732
733
734 void
FilterBuffer(BBuffer * buffer)735 EqualizerNode::FilterBuffer(BBuffer* buffer)
736 {
737 uint32 m_frameSize = (fFormat.u.raw_audio.format & 0x0f)
738 * fFormat.u.raw_audio.channel_count;
739 uint32 samples = buffer->Header()->size_used / m_frameSize;
740 uint32 channels = fFormat.u.raw_audio.channel_count;
741 if (fMute != 0)
742 memset(buffer->Data(), 0, buffer->Header()->size_used);
743 else if (fByPass == 0)
744 fEqualizer.ProcessBuffer((float*)buffer->Data(), samples * channels);
745 }
746