xref: /haiku/src/add-ons/media/media-add-ons/equalizer/EqualizerNode.cpp (revision 56bc38cef0bd924bac22f605e7ae493996e506b1)
171c77851Sthreedeyes /*
2*56bc38ceSPhilippe Saint-Pierre  * Copyright 2012, Gerasim Troeglazov (3dEyes**), 3dEyes@gmail.com.
3*56bc38ceSPhilippe Saint-Pierre  * All rights reserved.
471c77851Sthreedeyes  * Distributed under the terms of the MIT License.
571c77851Sthreedeyes  */
671c77851Sthreedeyes 
771c77851Sthreedeyes #include <ByteOrder.h>
871c77851Sthreedeyes #include <Buffer.h>
971c77851Sthreedeyes #include <BufferGroup.h>
1071c77851Sthreedeyes #include <TimeSource.h>
1171c77851Sthreedeyes #include <ParameterWeb.h>
1271c77851Sthreedeyes #include <String.h>
1371c77851Sthreedeyes 
1471c77851Sthreedeyes #include <stdio.h>
1571c77851Sthreedeyes #include <string.h>
1671c77851Sthreedeyes 
1771c77851Sthreedeyes #include "EqualizerNode.h"
1871c77851Sthreedeyes 
1971c77851Sthreedeyes //EqualizerNode
20*56bc38ceSPhilippe Saint-Pierre EqualizerNode::~EqualizerNode()
21*56bc38ceSPhilippe Saint-Pierre {
2271c77851Sthreedeyes 	Quit();
2371c77851Sthreedeyes }
2471c77851Sthreedeyes 
25*56bc38ceSPhilippe Saint-Pierre 
26*56bc38ceSPhilippe Saint-Pierre EqualizerNode::EqualizerNode(BMediaAddOn* addon)
27*56bc38ceSPhilippe Saint-Pierre 	:
2871c77851Sthreedeyes 	BMediaNode("10 Band Equalizer"),
2971c77851Sthreedeyes 	BBufferConsumer(B_MEDIA_RAW_AUDIO),
3071c77851Sthreedeyes 	BBufferProducer(B_MEDIA_RAW_AUDIO),
3171c77851Sthreedeyes 	BControllable(),
3271c77851Sthreedeyes 	BMediaEventLooper(),
3371c77851Sthreedeyes 	fAddOn(addon),
3471c77851Sthreedeyes 	fProcessLatency(0),
3571c77851Sthreedeyes 	fDownstreamLatency(0),
3671c77851Sthreedeyes 	fOutputMediaEnabled(true)
3771c77851Sthreedeyes {
3871c77851Sthreedeyes }
3971c77851Sthreedeyes 
40*56bc38ceSPhilippe Saint-Pierre 
4171c77851Sthreedeyes //BMediaNode
4271c77851Sthreedeyes BMediaAddOn*
4371c77851Sthreedeyes EqualizerNode::AddOn(int32* id) const
4471c77851Sthreedeyes {
4571c77851Sthreedeyes 	if (fAddOn)
4671c77851Sthreedeyes 		*id = 0;
4771c77851Sthreedeyes 	return fAddOn;
4871c77851Sthreedeyes }
4971c77851Sthreedeyes 
50*56bc38ceSPhilippe Saint-Pierre 
5171c77851Sthreedeyes status_t
5271c77851Sthreedeyes EqualizerNode::HandleMessage(int32 message, const void *data, size_t size)
5371c77851Sthreedeyes {
5471c77851Sthreedeyes 	if ((BControllable::HandleMessage(message, data, size) != B_OK) &&
5571c77851Sthreedeyes 		(BBufferConsumer::HandleMessage(message, data, size) != B_OK) &&
5671c77851Sthreedeyes 		(BBufferProducer::HandleMessage(message, data, size) != B_OK) &&
5771c77851Sthreedeyes 		(BControllable::HandleMessage(message, data, size) != B_OK)) {
5871c77851Sthreedeyes 		BMediaNode::HandleMessage(message, data, size);
5971c77851Sthreedeyes 		return B_OK;
60*56bc38ceSPhilippe Saint-Pierre 	}
6171c77851Sthreedeyes 	BMediaNode::HandleBadMessage(message, data, size);
6271c77851Sthreedeyes 	return B_ERROR;
6371c77851Sthreedeyes }
64*56bc38ceSPhilippe Saint-Pierre 
6571c77851Sthreedeyes 
6671c77851Sthreedeyes void
6771c77851Sthreedeyes EqualizerNode::NodeRegistered()
6871c77851Sthreedeyes {
6971c77851Sthreedeyes 	SetPriority(B_REAL_TIME_PRIORITY);
7071c77851Sthreedeyes 	Run();
7171c77851Sthreedeyes 
7271c77851Sthreedeyes 	fPreferredFormat.type = B_MEDIA_RAW_AUDIO;
7371c77851Sthreedeyes 	fPreferredFormat.u.raw_audio.buffer_size = BUFF_SIZE;
7471c77851Sthreedeyes 	fPreferredFormat.u.raw_audio = media_raw_audio_format::wildcard;
75*56bc38ceSPhilippe Saint-Pierre 	fPreferredFormat.u.raw_audio.channel_count =
76*56bc38ceSPhilippe Saint-Pierre 		media_raw_audio_format::wildcard.channel_count;
7771c77851Sthreedeyes 	fPreferredFormat.u.raw_audio.format = media_raw_audio_format::B_AUDIO_FLOAT;
7871c77851Sthreedeyes 
7971c77851Sthreedeyes 	fFormat.type = B_MEDIA_RAW_AUDIO;
8071c77851Sthreedeyes 	fFormat.u.raw_audio = media_raw_audio_format::wildcard;
8171c77851Sthreedeyes 
8271c77851Sthreedeyes 	fInputMedia.destination.port = ControlPort();
8371c77851Sthreedeyes 	fInputMedia.destination.id = ID_AUDIO_INPUT;
8471c77851Sthreedeyes 	fInputMedia.node = Node();
8571c77851Sthreedeyes 	fInputMedia.source = media_source::null;
8671c77851Sthreedeyes 	fInputMedia.format = fFormat;
8771c77851Sthreedeyes 	strncpy(fInputMedia.name, "Audio Input", B_MEDIA_NAME_LENGTH);
8871c77851Sthreedeyes 
8971c77851Sthreedeyes 	fOutputMedia.source.port = ControlPort();
9071c77851Sthreedeyes 	fOutputMedia.source.id = ID_AUDIO_OUTPUT;
9171c77851Sthreedeyes 	fOutputMedia.node = Node();
9271c77851Sthreedeyes 	fOutputMedia.destination = media_destination::null;
9371c77851Sthreedeyes 	fOutputMedia.format = fFormat;
9471c77851Sthreedeyes 	strncpy(fOutputMedia.name, "Audio Output", B_MEDIA_NAME_LENGTH);
9571c77851Sthreedeyes 
9671c77851Sthreedeyes 	InitParameterValues();
9771c77851Sthreedeyes 	InitParameterWeb();
9871c77851Sthreedeyes }
9971c77851Sthreedeyes 
100*56bc38ceSPhilippe Saint-Pierre 
10171c77851Sthreedeyes //BControllable
10271c77851Sthreedeyes status_t
103*56bc38ceSPhilippe Saint-Pierre EqualizerNode::GetParameterValue(int32 id, bigtime_t* lastChangeTime,
104*56bc38ceSPhilippe Saint-Pierre 	void* value, size_t* size)
10571c77851Sthreedeyes {
106*56bc38ceSPhilippe Saint-Pierre 	if (*size < sizeof(float))
10771c77851Sthreedeyes 		return B_NO_MEMORY;
10871c77851Sthreedeyes 
10971c77851Sthreedeyes 	if (id == P_MUTE) {
11071c77851Sthreedeyes 		*(int32*)value = fMute;
11171c77851Sthreedeyes 		*lastChangeTime = fMuteLastChanged;
11271c77851Sthreedeyes 		*size = sizeof(int32);
11371c77851Sthreedeyes 	} else if (id == P_BYPASS) {
11471c77851Sthreedeyes 		*(int32*)value = fByPass;
11571c77851Sthreedeyes 		*lastChangeTime = fByPassLastChanged;
11671c77851Sthreedeyes 		*size = sizeof(int32);
11771c77851Sthreedeyes 	} else if (id == P_PREAMP) {
11871c77851Sthreedeyes 		*(float*)value = (float)fEqualizer.PreAmp();
11971c77851Sthreedeyes 		*lastChangeTime = fPreAmpLastChanged;
12071c77851Sthreedeyes 		*size = sizeof(float);
12171c77851Sthreedeyes 	} else if (id >= P_BANDS && id < P_BANDS + fEqualizer.BandCount()) {
12271c77851Sthreedeyes 		int band = id - P_BANDS;
12371c77851Sthreedeyes 		*(float*)value = (float)fEqualizer.Band(band);
12471c77851Sthreedeyes 		*lastChangeTime = fBandsLastChanged[band];
12571c77851Sthreedeyes 		*size = sizeof(float);
126*56bc38ceSPhilippe Saint-Pierre 	} else
127*56bc38ceSPhilippe Saint-Pierre 		return B_ERROR;
12871c77851Sthreedeyes 	return B_OK;
12971c77851Sthreedeyes }
13071c77851Sthreedeyes 
13171c77851Sthreedeyes 
13271c77851Sthreedeyes void
133*56bc38ceSPhilippe Saint-Pierre EqualizerNode::SetParameterValue(int32 id, bigtime_t time, const void* value,
134*56bc38ceSPhilippe Saint-Pierre 	size_t size)
13571c77851Sthreedeyes {
136*56bc38ceSPhilippe Saint-Pierre 	if (id == P_PREAMP || id == P_BYPASS || id == P_MUTE
137*56bc38ceSPhilippe Saint-Pierre 		|| (id >= P_BANDS && id < P_BANDS + fEqualizer.BandCount())) {
13871c77851Sthreedeyes 		media_timed_event ev(time, BTimedEventQueue::B_PARAMETER, (void*)value,
13971c77851Sthreedeyes 							BTimedEventQueue::B_NO_CLEANUP, size, id, "EQ");
140*56bc38ceSPhilippe Saint-Pierre 		ParameterEventProcessing(&ev);
141*56bc38ceSPhilippe Saint-Pierre 			//dirty hack for parameter processing (mediakit bug????)
14271c77851Sthreedeyes 		EventQueue()->AddEvent(ev);
14371c77851Sthreedeyes 	}
14471c77851Sthreedeyes }
14571c77851Sthreedeyes 
146*56bc38ceSPhilippe Saint-Pierre 
14771c77851Sthreedeyes //BBufferConsumer
14871c77851Sthreedeyes void
14971c77851Sthreedeyes EqualizerNode::BufferReceived(BBuffer* buffer)
15071c77851Sthreedeyes {
15171c77851Sthreedeyes 	if (buffer->Header()->destination != fInputMedia.destination.id) {
15271c77851Sthreedeyes 		buffer->Recycle();
15371c77851Sthreedeyes 		return;
15471c77851Sthreedeyes 	}
15571c77851Sthreedeyes 
156*56bc38ceSPhilippe Saint-Pierre 	if (fOutputMedia.destination == media_destination::null
157*56bc38ceSPhilippe Saint-Pierre 		|| !fOutputMediaEnabled) {
15871c77851Sthreedeyes 		buffer->Recycle();
15971c77851Sthreedeyes 		return;
16071c77851Sthreedeyes 	}
16171c77851Sthreedeyes 
16271c77851Sthreedeyes 	FilterBuffer(buffer);
16371c77851Sthreedeyes 
164*56bc38ceSPhilippe Saint-Pierre 	status_t err = SendBuffer(buffer, fOutputMedia.source,
165*56bc38ceSPhilippe Saint-Pierre 		fOutputMedia.destination);
166*56bc38ceSPhilippe Saint-Pierre 	if (err < B_OK)
16771c77851Sthreedeyes 		buffer->Recycle();
16871c77851Sthreedeyes }
169*56bc38ceSPhilippe Saint-Pierre 
17071c77851Sthreedeyes 
17171c77851Sthreedeyes status_t
17271c77851Sthreedeyes EqualizerNode::AcceptFormat(const media_destination &dst, media_format* format)
17371c77851Sthreedeyes {
174*56bc38ceSPhilippe Saint-Pierre 	if (dst != fInputMedia.destination)
17571c77851Sthreedeyes 		return B_MEDIA_BAD_DESTINATION;
17671c77851Sthreedeyes 
177*56bc38ceSPhilippe Saint-Pierre 	if (format->type != B_MEDIA_RAW_AUDIO)
178*56bc38ceSPhilippe Saint-Pierre 		return B_MEDIA_BAD_FORMAT;
179*56bc38ceSPhilippe Saint-Pierre 
180*56bc38ceSPhilippe Saint-Pierre 	ValidateFormat((fFormat.u.raw_audio.format
181*56bc38ceSPhilippe Saint-Pierre 			!= media_raw_audio_format::wildcard.format) ?
18271c77851Sthreedeyes 		fFormat : fPreferredFormat, *format);
18371c77851Sthreedeyes 
18471c77851Sthreedeyes 	return B_OK;
18571c77851Sthreedeyes }
18671c77851Sthreedeyes 
187*56bc38ceSPhilippe Saint-Pierre 
18871c77851Sthreedeyes status_t
18971c77851Sthreedeyes EqualizerNode::GetNextInput(int32* cookie, media_input* input)
19071c77851Sthreedeyes {
191*56bc38ceSPhilippe Saint-Pierre 	if (*cookie)
19271c77851Sthreedeyes 		return B_BAD_INDEX;
193*56bc38ceSPhilippe Saint-Pierre 
19471c77851Sthreedeyes 	++*cookie;
19571c77851Sthreedeyes 	*input = fInputMedia;
19671c77851Sthreedeyes 	return B_OK;
19771c77851Sthreedeyes }
19871c77851Sthreedeyes 
199*56bc38ceSPhilippe Saint-Pierre 
20071c77851Sthreedeyes void
20171c77851Sthreedeyes EqualizerNode::DisposeInputCookie(int32 cookie)
20271c77851Sthreedeyes {
20371c77851Sthreedeyes }
20471c77851Sthreedeyes 
205*56bc38ceSPhilippe Saint-Pierre 
20671c77851Sthreedeyes status_t
207*56bc38ceSPhilippe Saint-Pierre EqualizerNode::FormatChanged(const media_source &src,
208*56bc38ceSPhilippe Saint-Pierre 	const media_destination &dst, int32 changeTag, const media_format &format)
20971c77851Sthreedeyes {
21071c77851Sthreedeyes 	return B_MEDIA_BAD_FORMAT;
21171c77851Sthreedeyes }
21271c77851Sthreedeyes 
213*56bc38ceSPhilippe Saint-Pierre 
21471c77851Sthreedeyes void
215*56bc38ceSPhilippe Saint-Pierre EqualizerNode::ProducerDataStatus(const media_destination &dst, int32 status,
216*56bc38ceSPhilippe Saint-Pierre 	bigtime_t when)
21771c77851Sthreedeyes {
218*56bc38ceSPhilippe Saint-Pierre 	if (fOutputMedia.destination != media_destination::null)
21971c77851Sthreedeyes 		SendDataStatus(status, fOutputMedia.destination, when);
22071c77851Sthreedeyes }
221*56bc38ceSPhilippe Saint-Pierre 
22271c77851Sthreedeyes 
22371c77851Sthreedeyes status_t
22471c77851Sthreedeyes EqualizerNode::GetLatencyFor(const media_destination &dst, bigtime_t* latency,
22571c77851Sthreedeyes 	media_node_id* outTimeSource)
22671c77851Sthreedeyes {
22771c77851Sthreedeyes 
228*56bc38ceSPhilippe Saint-Pierre 	if (dst != fInputMedia.destination)
22971c77851Sthreedeyes 		return B_MEDIA_BAD_DESTINATION;
23071c77851Sthreedeyes 
23171c77851Sthreedeyes 	*latency = fDownstreamLatency + fProcessLatency;
23271c77851Sthreedeyes 	*outTimeSource = TimeSource()->ID();
23371c77851Sthreedeyes 	return B_OK;
23471c77851Sthreedeyes }
23571c77851Sthreedeyes 
236*56bc38ceSPhilippe Saint-Pierre 
23771c77851Sthreedeyes status_t
23871c77851Sthreedeyes EqualizerNode::Connected(const media_source& source,
23971c77851Sthreedeyes 	const media_destination& destination, const media_format& format,
24071c77851Sthreedeyes 	media_input* poInput)
24171c77851Sthreedeyes {
242*56bc38ceSPhilippe Saint-Pierre 	if (destination != fInputMedia.destination)
24371c77851Sthreedeyes 		return B_MEDIA_BAD_DESTINATION;
244*56bc38ceSPhilippe Saint-Pierre 
245*56bc38ceSPhilippe Saint-Pierre 	if (fInputMedia.source != media_source::null)
24671c77851Sthreedeyes 		return B_MEDIA_ALREADY_CONNECTED;
24771c77851Sthreedeyes 
24871c77851Sthreedeyes 	fInputMedia.source = source;
24971c77851Sthreedeyes 	fInputMedia.format = format;
25071c77851Sthreedeyes 	*poInput = fInputMedia;
25171c77851Sthreedeyes 	fFormat = format;
25271c77851Sthreedeyes 
25371c77851Sthreedeyes 	return B_OK;
25471c77851Sthreedeyes }
25571c77851Sthreedeyes 
256*56bc38ceSPhilippe Saint-Pierre 
25771c77851Sthreedeyes void
258*56bc38ceSPhilippe Saint-Pierre EqualizerNode::Disconnected(const media_source &src,
259*56bc38ceSPhilippe Saint-Pierre 	const media_destination &dst)
26071c77851Sthreedeyes {
261*56bc38ceSPhilippe Saint-Pierre 	if (fInputMedia.source != src || dst != fInputMedia.destination)
26271c77851Sthreedeyes 		return;
263*56bc38ceSPhilippe Saint-Pierre 
26471c77851Sthreedeyes 	fInputMedia.source = media_source::null;
26571c77851Sthreedeyes 
266*56bc38ceSPhilippe Saint-Pierre 	if (fOutputMedia.destination == media_destination::null)
26771c77851Sthreedeyes 		fFormat.u.raw_audio = media_raw_audio_format::wildcard;
268*56bc38ceSPhilippe Saint-Pierre 
26971c77851Sthreedeyes 	fInputMedia.format = fFormat;
27071c77851Sthreedeyes }
27171c77851Sthreedeyes 
272*56bc38ceSPhilippe Saint-Pierre 
27371c77851Sthreedeyes //BBufferProducer
27471c77851Sthreedeyes status_t
275*56bc38ceSPhilippe Saint-Pierre EqualizerNode::FormatSuggestionRequested(media_type type, int32 quality,
276*56bc38ceSPhilippe Saint-Pierre 	media_format* format)
27771c77851Sthreedeyes {
278*56bc38ceSPhilippe Saint-Pierre 	if (type != B_MEDIA_RAW_AUDIO)
27971c77851Sthreedeyes 		return B_MEDIA_BAD_FORMAT;
28071c77851Sthreedeyes 
281*56bc38ceSPhilippe Saint-Pierre 	if (fFormat.u.raw_audio.format != media_raw_audio_format::wildcard.format)
28271c77851Sthreedeyes 		*format = fFormat;
283*56bc38ceSPhilippe Saint-Pierre 	else
28471c77851Sthreedeyes 		*format = fPreferredFormat;
28571c77851Sthreedeyes 	return B_OK;
28671c77851Sthreedeyes }
28771c77851Sthreedeyes 
288*56bc38ceSPhilippe Saint-Pierre 
28971c77851Sthreedeyes status_t
29071c77851Sthreedeyes EqualizerNode::FormatProposal(const media_source &src, media_format* format)
29171c77851Sthreedeyes {
292*56bc38ceSPhilippe Saint-Pierre 	if (src != fOutputMedia.source)
29371c77851Sthreedeyes 		return B_MEDIA_BAD_SOURCE;
29471c77851Sthreedeyes 
295*56bc38ceSPhilippe Saint-Pierre 	if (format->type != B_MEDIA_RAW_AUDIO)
29671c77851Sthreedeyes 		return B_MEDIA_BAD_FORMAT;
29771c77851Sthreedeyes 
298*56bc38ceSPhilippe Saint-Pierre 	ValidateFormat((fFormat.u.raw_audio.format
299*56bc38ceSPhilippe Saint-Pierre 			!= media_raw_audio_format::wildcard.format) ?
30071c77851Sthreedeyes 		fFormat:fPreferredFormat, *format);
30171c77851Sthreedeyes 
30271c77851Sthreedeyes 	return B_OK;
30371c77851Sthreedeyes }
30471c77851Sthreedeyes 
305*56bc38ceSPhilippe Saint-Pierre 
30671c77851Sthreedeyes status_t
307*56bc38ceSPhilippe Saint-Pierre EqualizerNode::FormatChangeRequested(const media_source &src,
308*56bc38ceSPhilippe Saint-Pierre 	const media_destination &dst, media_format* format, int32* _deprecated_)
30971c77851Sthreedeyes {
31071c77851Sthreedeyes 	return B_MEDIA_BAD_FORMAT;
31171c77851Sthreedeyes }
31271c77851Sthreedeyes 
313*56bc38ceSPhilippe Saint-Pierre 
31471c77851Sthreedeyes void
315*56bc38ceSPhilippe Saint-Pierre EqualizerNode::LateNoticeReceived(const media_source &src, bigtime_t late,
316*56bc38ceSPhilippe Saint-Pierre 	bigtime_t when)
31771c77851Sthreedeyes {
318*56bc38ceSPhilippe Saint-Pierre 	if (src != fOutputMedia.source || fInputMedia.source == media_source::null)
31971c77851Sthreedeyes 		return;
320*56bc38ceSPhilippe Saint-Pierre 
32171c77851Sthreedeyes 	NotifyLateProducer(fInputMedia.source, late, when);
32271c77851Sthreedeyes }
32371c77851Sthreedeyes 
324*56bc38ceSPhilippe Saint-Pierre 
32571c77851Sthreedeyes status_t
32671c77851Sthreedeyes EqualizerNode::GetNextOutput(int32* cookie, media_output* output)
32771c77851Sthreedeyes {
328*56bc38ceSPhilippe Saint-Pierre 	if (*cookie)
32971c77851Sthreedeyes 		return B_BAD_INDEX;
330*56bc38ceSPhilippe Saint-Pierre 
33171c77851Sthreedeyes 	++*cookie;
33271c77851Sthreedeyes 	*output = fOutputMedia;
33371c77851Sthreedeyes 	return B_OK;
33471c77851Sthreedeyes }
33571c77851Sthreedeyes 
336*56bc38ceSPhilippe Saint-Pierre 
33771c77851Sthreedeyes status_t
33871c77851Sthreedeyes EqualizerNode::DisposeOutputCookie(int32 cookie)
33971c77851Sthreedeyes {
34071c77851Sthreedeyes 	return B_OK;
34171c77851Sthreedeyes }
34271c77851Sthreedeyes 
343*56bc38ceSPhilippe Saint-Pierre 
34471c77851Sthreedeyes status_t
34571c77851Sthreedeyes EqualizerNode::SetBufferGroup(const media_source &src, BBufferGroup* group)
34671c77851Sthreedeyes {
34771c77851Sthreedeyes 	int32 changeTag;
34871c77851Sthreedeyes 	status_t ret = B_OK;
34971c77851Sthreedeyes 
350*56bc38ceSPhilippe Saint-Pierre 	if (src != fOutputMedia.source)
35171c77851Sthreedeyes 		return B_MEDIA_BAD_SOURCE;
35271c77851Sthreedeyes 
353*56bc38ceSPhilippe Saint-Pierre 	if (fInputMedia.source == media_source::null)
354*56bc38ceSPhilippe Saint-Pierre 		return B_ERROR;
355*56bc38ceSPhilippe Saint-Pierre 
356*56bc38ceSPhilippe Saint-Pierre 	ret = SetOutputBuffersFor(fInputMedia.source, fInputMedia.destination,
357*56bc38ceSPhilippe Saint-Pierre 		group, 0, &changeTag);
35871c77851Sthreedeyes 	return ret;
35971c77851Sthreedeyes }
36071c77851Sthreedeyes 
361*56bc38ceSPhilippe Saint-Pierre 
36271c77851Sthreedeyes status_t
363*56bc38ceSPhilippe Saint-Pierre EqualizerNode::PrepareToConnect(const media_source &src,
364*56bc38ceSPhilippe Saint-Pierre 	const media_destination &dst, media_format* format, media_source* outSource,
365*56bc38ceSPhilippe Saint-Pierre 	char* outName)
36671c77851Sthreedeyes {
367*56bc38ceSPhilippe Saint-Pierre 	if (src != fOutputMedia.source)
36871c77851Sthreedeyes 		return B_MEDIA_BAD_SOURCE;
36971c77851Sthreedeyes 
370*56bc38ceSPhilippe Saint-Pierre 	if (format->type != B_MEDIA_RAW_AUDIO)
37171c77851Sthreedeyes 		return B_MEDIA_BAD_FORMAT;
37271c77851Sthreedeyes 
373*56bc38ceSPhilippe Saint-Pierre 	if (fOutputMedia.destination != media_destination::null)
37471c77851Sthreedeyes 		return B_MEDIA_ALREADY_CONNECTED;
37571c77851Sthreedeyes 
376*56bc38ceSPhilippe Saint-Pierre 	status_t err = ValidateFormat((fFormat.u.raw_audio.format
377*56bc38ceSPhilippe Saint-Pierre 			!= media_raw_audio_format::wildcard.format) ? fFormat
378*56bc38ceSPhilippe Saint-Pierre 		: fPreferredFormat, *format);
37971c77851Sthreedeyes 
380*56bc38ceSPhilippe Saint-Pierre 	if (err < B_OK)
38171c77851Sthreedeyes 		return err;
38271c77851Sthreedeyes 
38371c77851Sthreedeyes 	SetOutputFormat(*format);
38471c77851Sthreedeyes 
38571c77851Sthreedeyes 	fOutputMedia.destination = dst;
38671c77851Sthreedeyes 	fOutputMedia.format = *format;
38771c77851Sthreedeyes 
38871c77851Sthreedeyes 	*outSource = fOutputMedia.source;
38971c77851Sthreedeyes 	strncpy(outName, fOutputMedia.name, B_MEDIA_NAME_LENGTH);
39071c77851Sthreedeyes 
39171c77851Sthreedeyes 	return B_OK;
39271c77851Sthreedeyes }
39371c77851Sthreedeyes 
394*56bc38ceSPhilippe Saint-Pierre 
39571c77851Sthreedeyes void
396*56bc38ceSPhilippe Saint-Pierre EqualizerNode::Connect(status_t status, const media_source &src,
397*56bc38ceSPhilippe Saint-Pierre 	const media_destination &dst, const media_format &format, char* outName)
39871c77851Sthreedeyes {
39971c77851Sthreedeyes 	status_t err;
40071c77851Sthreedeyes 	if (status < B_OK) {
40171c77851Sthreedeyes 		fOutputMedia.destination = media_destination::null;
40271c77851Sthreedeyes 		return;
40371c77851Sthreedeyes 	}
40471c77851Sthreedeyes 
40571c77851Sthreedeyes 	strncpy(outName, fOutputMedia.name, B_MEDIA_NAME_LENGTH);
40671c77851Sthreedeyes 	fOutputMedia.destination = dst;
40771c77851Sthreedeyes 	fFormat = format;
40871c77851Sthreedeyes 
40971c77851Sthreedeyes 	media_node_id timeSource;
410*56bc38ceSPhilippe Saint-Pierre 	err = FindLatencyFor(fOutputMedia.destination, &fDownstreamLatency,
411*56bc38ceSPhilippe Saint-Pierre 		&timeSource);
41271c77851Sthreedeyes 
41371c77851Sthreedeyes 	InitFilter();
41471c77851Sthreedeyes 
41571c77851Sthreedeyes 	fProcessLatency = GetFilterLatency();
41671c77851Sthreedeyes 	SetEventLatency(fDownstreamLatency + fProcessLatency);
41771c77851Sthreedeyes 
41871c77851Sthreedeyes 	if (fInputMedia.source != media_source::null) {
41971c77851Sthreedeyes 		SendLatencyChange(fInputMedia.source, fInputMedia.destination,
42071c77851Sthreedeyes 			EventLatency() + SchedulingLatency());
42171c77851Sthreedeyes 	}
42271c77851Sthreedeyes 
42371c77851Sthreedeyes 	bigtime_t duration = 0;
42471c77851Sthreedeyes 
425*56bc38ceSPhilippe Saint-Pierre 	int sample_size = (fFormat.u.raw_audio.format & 0xf)
426*56bc38ceSPhilippe Saint-Pierre 		* fFormat.u.raw_audio.channel_count;
42771c77851Sthreedeyes 
428*56bc38ceSPhilippe Saint-Pierre 	if (fFormat.u.raw_audio.buffer_size > 0
429*56bc38ceSPhilippe Saint-Pierre 		&& fFormat.u.raw_audio.frame_rate > 0 && sample_size > 0) {
430*56bc38ceSPhilippe Saint-Pierre 		duration = (bigtime_t)(((fFormat.u.raw_audio.buffer_size / sample_size)
431*56bc38ceSPhilippe Saint-Pierre 			/ fFormat.u.raw_audio.frame_rate) * 1000000.0);
43271c77851Sthreedeyes 	}
43371c77851Sthreedeyes 
43471c77851Sthreedeyes 	SetBufferDuration(duration);
43571c77851Sthreedeyes }
43671c77851Sthreedeyes 
437*56bc38ceSPhilippe Saint-Pierre 
43871c77851Sthreedeyes void
43971c77851Sthreedeyes EqualizerNode::Disconnect(const media_source &src, const media_destination &dst)
44071c77851Sthreedeyes {
441*56bc38ceSPhilippe Saint-Pierre 	if (src != fOutputMedia.source)
44271c77851Sthreedeyes 		return;
44371c77851Sthreedeyes 
444*56bc38ceSPhilippe Saint-Pierre 	if (dst != fOutputMedia.destination)
44571c77851Sthreedeyes 		return;
44671c77851Sthreedeyes 
44771c77851Sthreedeyes 	fOutputMedia.destination = media_destination::null;
44871c77851Sthreedeyes 
449*56bc38ceSPhilippe Saint-Pierre 	if (fInputMedia.source == media_source::null)
45071c77851Sthreedeyes 		fFormat.u.raw_audio = media_raw_audio_format::wildcard;
45171c77851Sthreedeyes 
45271c77851Sthreedeyes 	fOutputMedia.format = fFormat;
45371c77851Sthreedeyes }
45471c77851Sthreedeyes 
455*56bc38ceSPhilippe Saint-Pierre 
45671c77851Sthreedeyes void
457*56bc38ceSPhilippe Saint-Pierre EqualizerNode::EnableOutput(const media_source &src, bool enabled,
458*56bc38ceSPhilippe Saint-Pierre 	int32* _deprecated_)
45971c77851Sthreedeyes {
460*56bc38ceSPhilippe Saint-Pierre 	if (src != fOutputMedia.source)
46171c77851Sthreedeyes 		return;
46271c77851Sthreedeyes 	fOutputMediaEnabled = enabled;
46371c77851Sthreedeyes }
46471c77851Sthreedeyes 
465*56bc38ceSPhilippe Saint-Pierre 
46671c77851Sthreedeyes status_t
46771c77851Sthreedeyes EqualizerNode::GetLatency(bigtime_t* latency)
46871c77851Sthreedeyes {
46971c77851Sthreedeyes 	*latency = EventLatency() + SchedulingLatency();
47071c77851Sthreedeyes 	return B_OK;
47171c77851Sthreedeyes }
47271c77851Sthreedeyes 
473*56bc38ceSPhilippe Saint-Pierre 
47471c77851Sthreedeyes void
475*56bc38ceSPhilippe Saint-Pierre EqualizerNode::LatencyChanged(const media_source &src,
476*56bc38ceSPhilippe Saint-Pierre 	const media_destination &dst, bigtime_t latency, uint32 flags)
47771c77851Sthreedeyes {
478*56bc38ceSPhilippe Saint-Pierre 	if (src != fOutputMedia.source || dst != fOutputMedia.destination)
47971c77851Sthreedeyes 		return;
48071c77851Sthreedeyes 
48171c77851Sthreedeyes 	fDownstreamLatency = latency;
48271c77851Sthreedeyes 	SetEventLatency(fDownstreamLatency + fProcessLatency);
48371c77851Sthreedeyes 
48471c77851Sthreedeyes 	if (fInputMedia.source != media_source::null) {
48571c77851Sthreedeyes 		SendLatencyChange(fInputMedia.source,
48671c77851Sthreedeyes 			fInputMedia.destination,EventLatency() + SchedulingLatency());
48771c77851Sthreedeyes 	}
48871c77851Sthreedeyes }
48971c77851Sthreedeyes 
490*56bc38ceSPhilippe Saint-Pierre 
49171c77851Sthreedeyes //BMediaEventLooper
49271c77851Sthreedeyes bigtime_t
49371c77851Sthreedeyes EqualizerNode::OfflineTime()
49471c77851Sthreedeyes {
49571c77851Sthreedeyes 	return 0LL;
49671c77851Sthreedeyes }
49771c77851Sthreedeyes 
498*56bc38ceSPhilippe Saint-Pierre 
49971c77851Sthreedeyes //EqualizerNode
50071c77851Sthreedeyes void
501*56bc38ceSPhilippe Saint-Pierre EqualizerNode::HandleEvent(const media_timed_event* event, bigtime_t late,
502*56bc38ceSPhilippe Saint-Pierre 	bool realTime)
50371c77851Sthreedeyes {
504*56bc38ceSPhilippe Saint-Pierre 	if (event->type == BTimedEventQueue::B_PARAMETER)
50571c77851Sthreedeyes 		ParameterEventProcessing(event);
50671c77851Sthreedeyes }
50771c77851Sthreedeyes 
50871c77851Sthreedeyes 
50971c77851Sthreedeyes void
51071c77851Sthreedeyes EqualizerNode::ParameterEventProcessing(const media_timed_event* event)
51171c77851Sthreedeyes {
51271c77851Sthreedeyes 	float value = 0.0;
51371c77851Sthreedeyes 	int32 value32 = 0;
51471c77851Sthreedeyes 
51571c77851Sthreedeyes 	int32 id = event->bigdata;
51671c77851Sthreedeyes 	size_t size = event->data;
51771c77851Sthreedeyes 	bigtime_t now = TimeSource()->Now();
51871c77851Sthreedeyes 
51971c77851Sthreedeyes 	type_code v_type = B_FLOAT_TYPE;
52071c77851Sthreedeyes 
52171c77851Sthreedeyes 	BParameter* web_param;
52271c77851Sthreedeyes 
52371c77851Sthreedeyes 	for (int i = 0; i < fWeb->CountParameters(); i++) {
52471c77851Sthreedeyes 		web_param = fWeb->ParameterAt(i);
52571c77851Sthreedeyes 		if (web_param->ID() == id) {
52671c77851Sthreedeyes 			v_type=web_param->ValueType();
52771c77851Sthreedeyes 			break;
52871c77851Sthreedeyes 		}
52971c77851Sthreedeyes 	}
53071c77851Sthreedeyes 
53171c77851Sthreedeyes 	if (v_type == B_FLOAT_TYPE)
53271c77851Sthreedeyes 		value = *((float*)event->pointer);
533*56bc38ceSPhilippe Saint-Pierre 	else if (v_type == B_INT32_TYPE) {
53471c77851Sthreedeyes 		value32 = *((int32*)event->pointer);
53571c77851Sthreedeyes 		value = (float)value32;
53671c77851Sthreedeyes 	}
53771c77851Sthreedeyes 
53871c77851Sthreedeyes 	if (id == P_MUTE) {
53971c77851Sthreedeyes 		fMute = value32;
54071c77851Sthreedeyes 		fMuteLastChanged = now;
54171c77851Sthreedeyes 		BroadcastNewParameterValue(now,	id,	event->pointer, size);
54271c77851Sthreedeyes 	} else if (id == P_BYPASS) {
54371c77851Sthreedeyes 		fByPass = value32;
54471c77851Sthreedeyes 		fByPassLastChanged = now;
54571c77851Sthreedeyes 		BroadcastNewParameterValue(now,	id,	event->pointer, size);
54671c77851Sthreedeyes 	} else if (id == P_PREAMP) {
54771c77851Sthreedeyes 		if (value != fEqualizer.PreAmp()) {
54871c77851Sthreedeyes 			fEqualizer.SetPreAmp(value);
54971c77851Sthreedeyes 			fPreAmpLastChanged = now;
55071c77851Sthreedeyes 			BroadcastNewParameterValue(now,	id,	&value,	size);
55171c77851Sthreedeyes 		}
55271c77851Sthreedeyes 	} else if (id >= P_BANDS && id < P_BANDS + fEqualizer.BandCount()) {
55371c77851Sthreedeyes 		int band = id - P_BANDS;
55471c77851Sthreedeyes 		if (value != fEqualizer.Band(band)) {
55571c77851Sthreedeyes 			fEqualizer.SetBand(band, value);
55671c77851Sthreedeyes 			fBandsLastChanged[band] = now;
55771c77851Sthreedeyes 			BroadcastNewParameterValue(now,	id,	&value,	size);
55871c77851Sthreedeyes 		}
55971c77851Sthreedeyes 	}
56071c77851Sthreedeyes }
56171c77851Sthreedeyes 
562*56bc38ceSPhilippe Saint-Pierre 
56371c77851Sthreedeyes status_t
56471c77851Sthreedeyes EqualizerNode::ValidateFormat(const media_format &preferredFormat,
56571c77851Sthreedeyes 	media_format &format)
56671c77851Sthreedeyes {
56771c77851Sthreedeyes 	status_t ret = B_OK;
56871c77851Sthreedeyes 
56971c77851Sthreedeyes 	if (format.type != B_MEDIA_RAW_AUDIO) {
57071c77851Sthreedeyes 		format = preferredFormat;
57171c77851Sthreedeyes 		return B_MEDIA_BAD_FORMAT;
57271c77851Sthreedeyes 	}
57371c77851Sthreedeyes 
57471c77851Sthreedeyes 	media_raw_audio_format &wild = media_raw_audio_format::wildcard;
57571c77851Sthreedeyes 	media_raw_audio_format &f = format.u.raw_audio;
57671c77851Sthreedeyes 	const media_raw_audio_format &pref = format.u.raw_audio;
57771c77851Sthreedeyes 
57871c77851Sthreedeyes 	if (pref.frame_rate != wild.frame_rate && f.frame_rate != pref.frame_rate) {
579*56bc38ceSPhilippe Saint-Pierre 		if (f.frame_rate != wild.frame_rate)
58071c77851Sthreedeyes 			ret = B_MEDIA_BAD_FORMAT;
58171c77851Sthreedeyes 		f.frame_rate = pref.frame_rate;
58271c77851Sthreedeyes 	}
58371c77851Sthreedeyes 
584*56bc38ceSPhilippe Saint-Pierre 	if (pref.channel_count != wild.channel_count
585*56bc38ceSPhilippe Saint-Pierre 		&& f.channel_count != pref.channel_count) {
586*56bc38ceSPhilippe Saint-Pierre 		if (f.channel_count != wild.channel_count)
58771c77851Sthreedeyes 			ret = B_MEDIA_BAD_FORMAT;
58871c77851Sthreedeyes 		f.channel_count = pref.channel_count;
58971c77851Sthreedeyes 	}
59071c77851Sthreedeyes 
59171c77851Sthreedeyes 	if (pref.byte_order != wild.byte_order && f.byte_order != pref.byte_order) {
592*56bc38ceSPhilippe Saint-Pierre 		if (f.byte_order != wild.byte_order)
59371c77851Sthreedeyes 			ret = B_MEDIA_BAD_FORMAT;
59471c77851Sthreedeyes 		f.byte_order = pref.byte_order;
59571c77851Sthreedeyes 	}
59671c77851Sthreedeyes 
59771c77851Sthreedeyes 	if (pref.format != wild.format && f.format != pref.format) {
598*56bc38ceSPhilippe Saint-Pierre 		if (f.format != wild.format)
59971c77851Sthreedeyes 			ret = B_MEDIA_BAD_FORMAT;
60071c77851Sthreedeyes 		f.format = pref.format;
60171c77851Sthreedeyes 	}
60271c77851Sthreedeyes 
603*56bc38ceSPhilippe Saint-Pierre 	if (pref.buffer_size != wild.buffer_size
604*56bc38ceSPhilippe Saint-Pierre 		&& f.buffer_size != pref.buffer_size) {
605*56bc38ceSPhilippe Saint-Pierre 		if (f.buffer_size != wild.buffer_size)
60671c77851Sthreedeyes 			ret = B_MEDIA_BAD_FORMAT;
60771c77851Sthreedeyes 		f.buffer_size = pref.buffer_size;
60871c77851Sthreedeyes 	}
60971c77851Sthreedeyes 
61071c77851Sthreedeyes 	return ret;
61171c77851Sthreedeyes }
61271c77851Sthreedeyes 
613*56bc38ceSPhilippe Saint-Pierre 
61471c77851Sthreedeyes void
61571c77851Sthreedeyes EqualizerNode::SetOutputFormat(media_format &format)
61671c77851Sthreedeyes {
61771c77851Sthreedeyes 	media_raw_audio_format &f = format.u.raw_audio;
61871c77851Sthreedeyes 	media_raw_audio_format &w = media_raw_audio_format::wildcard;
61971c77851Sthreedeyes 
620*56bc38ceSPhilippe Saint-Pierre 	if (f.frame_rate == w.frame_rate)
62171c77851Sthreedeyes 		f.frame_rate = 44100.0;
62271c77851Sthreedeyes 
62371c77851Sthreedeyes 	if (f.channel_count == w.channel_count) {
624*56bc38ceSPhilippe Saint-Pierre 		if (fInputMedia.source != media_source::null)
62571c77851Sthreedeyes 			f.channel_count = fInputMedia.format.u.raw_audio.channel_count;
626*56bc38ceSPhilippe Saint-Pierre 		else
62771c77851Sthreedeyes 			f.channel_count = 2;
62871c77851Sthreedeyes 	}
62971c77851Sthreedeyes 
630*56bc38ceSPhilippe Saint-Pierre 	if (f.format == w.format)
63171c77851Sthreedeyes 		f.format = media_raw_audio_format::B_AUDIO_FLOAT;
63271c77851Sthreedeyes 
633*56bc38ceSPhilippe Saint-Pierre 	if (f.byte_order == w.format)
634*56bc38ceSPhilippe Saint-Pierre 		f.byte_order = (B_HOST_IS_BENDIAN) ? B_MEDIA_BIG_ENDIAN
635*56bc38ceSPhilippe Saint-Pierre 			: B_MEDIA_LITTLE_ENDIAN;
63671c77851Sthreedeyes 
637*56bc38ceSPhilippe Saint-Pierre 	if (f.buffer_size == w.buffer_size)
63871c77851Sthreedeyes 		f.buffer_size = BUFF_SIZE;
63971c77851Sthreedeyes }
640*56bc38ceSPhilippe Saint-Pierre 
64171c77851Sthreedeyes 
64271c77851Sthreedeyes void
64371c77851Sthreedeyes EqualizerNode::InitParameterValues()
64471c77851Sthreedeyes {
64571c77851Sthreedeyes 	fMute = 0;
64671c77851Sthreedeyes 	fByPass = 0;
64771c77851Sthreedeyes 	fMuteLastChanged = 0LL;
64871c77851Sthreedeyes 	fByPassLastChanged = 0LL;
64971c77851Sthreedeyes 	fPreAmpLastChanged = 0LL;
65071c77851Sthreedeyes 
651*56bc38ceSPhilippe Saint-Pierre 	for (int i = 0; i < EQ_BANDS; i++)
65271c77851Sthreedeyes 		fBandsLastChanged[i] = 0LL;
65371c77851Sthreedeyes 
65471c77851Sthreedeyes 	fEqualizer.CleanUp();
65571c77851Sthreedeyes }
65671c77851Sthreedeyes 
657*56bc38ceSPhilippe Saint-Pierre 
65871c77851Sthreedeyes void
65971c77851Sthreedeyes EqualizerNode::InitParameterWeb(void)
66071c77851Sthreedeyes {
66171c77851Sthreedeyes 	fWeb = new BParameterWeb();
66271c77851Sthreedeyes 
66371c77851Sthreedeyes 	BParameterGroup* fParamGroup = fWeb->MakeGroup("EqualizerNode Parameters");
66471c77851Sthreedeyes 	BParameterGroup* fFControlGroup = fParamGroup->MakeGroup("FilterControl");
66571c77851Sthreedeyes 
666*56bc38ceSPhilippe Saint-Pierre 	fFControlGroup->MakeDiscreteParameter(P_MUTE,B_MEDIA_NO_TYPE,"Mute",
667*56bc38ceSPhilippe Saint-Pierre 		B_ENABLE);
668*56bc38ceSPhilippe Saint-Pierre 	fFControlGroup->MakeDiscreteParameter(P_BYPASS,B_MEDIA_NO_TYPE,"ByPass",
669*56bc38ceSPhilippe Saint-Pierre 		B_ENABLE);
67071c77851Sthreedeyes 
67171c77851Sthreedeyes 	BNullParameter* label;
67271c77851Sthreedeyes 	BParameterGroup* group;
67371c77851Sthreedeyes 	BContinuousParameter* value;
67471c77851Sthreedeyes 
67571c77851Sthreedeyes 	group = fParamGroup->MakeGroup("Pre Amp");
676*56bc38ceSPhilippe Saint-Pierre 	label = group->MakeNullParameter(P_PREAMP_LABEL, B_MEDIA_NO_TYPE, "Pre Amp",
677*56bc38ceSPhilippe Saint-Pierre 		B_GENERIC);
678*56bc38ceSPhilippe Saint-Pierre 	value = group->MakeContinuousParameter(P_PREAMP, B_MEDIA_NO_TYPE, "",
679*56bc38ceSPhilippe Saint-Pierre 		B_GAIN, "dB", -8.0, 8.0, 0.1);
68071c77851Sthreedeyes 	label->AddOutput(value);
68171c77851Sthreedeyes 	value->AddInput(label);
68271c77851Sthreedeyes 
68371c77851Sthreedeyes 	for (int i = 0; i < fEqualizer.BandCount(); i++) {
68471c77851Sthreedeyes 		char freq[32];
68571c77851Sthreedeyes 		sprintf(freq,"%gHz",fEqualizer.BandFrequency(i));
68671c77851Sthreedeyes 		group = fParamGroup->MakeGroup(freq);
68771c77851Sthreedeyes 		label = group->MakeNullParameter(P_BAND_LABELS + i, B_MEDIA_NO_TYPE,
68871c77851Sthreedeyes 			freq, B_GENERIC);
68971c77851Sthreedeyes 		value = group->MakeContinuousParameter(P_BANDS + i, B_MEDIA_NO_TYPE,
69071c77851Sthreedeyes 			"", B_GAIN, "dB", -16.0, 16.0, 0.1);
69171c77851Sthreedeyes 		label->AddOutput(value);
69271c77851Sthreedeyes 		value->AddInput(label);
69371c77851Sthreedeyes 	}
69471c77851Sthreedeyes 
69571c77851Sthreedeyes 	SetParameterWeb(fWeb);
69671c77851Sthreedeyes }
69771c77851Sthreedeyes 
698*56bc38ceSPhilippe Saint-Pierre 
69971c77851Sthreedeyes void
70071c77851Sthreedeyes EqualizerNode::InitFilter(void)
70171c77851Sthreedeyes {
702*56bc38ceSPhilippe Saint-Pierre 	fEqualizer.SetFormat(fFormat.u.raw_audio.channel_count,
703*56bc38ceSPhilippe Saint-Pierre 		fFormat.u.raw_audio.frame_rate);
70471c77851Sthreedeyes }
70571c77851Sthreedeyes 
706*56bc38ceSPhilippe Saint-Pierre 
70771c77851Sthreedeyes bigtime_t
70871c77851Sthreedeyes EqualizerNode::GetFilterLatency(void)
70971c77851Sthreedeyes {
710*56bc38ceSPhilippe Saint-Pierre 	if (fOutputMedia.destination == media_destination::null)
71171c77851Sthreedeyes 		return 0LL;
71271c77851Sthreedeyes 
713*56bc38ceSPhilippe Saint-Pierre 	BBufferGroup* test_group =
714*56bc38ceSPhilippe Saint-Pierre 		new BBufferGroup(fOutputMedia.format.u.raw_audio.buffer_size, 1);
71571c77851Sthreedeyes 
716*56bc38ceSPhilippe Saint-Pierre 	BBuffer* buffer =
717*56bc38ceSPhilippe Saint-Pierre 		test_group->RequestBuffer(fOutputMedia.format.u.raw_audio.buffer_size);
71871c77851Sthreedeyes 	buffer->Header()->type = B_MEDIA_RAW_AUDIO;
71971c77851Sthreedeyes 	buffer->Header()->size_used = fOutputMedia.format.u.raw_audio.buffer_size;
72071c77851Sthreedeyes 
72171c77851Sthreedeyes 	bigtime_t begin = system_time();
72271c77851Sthreedeyes 	FilterBuffer(buffer);
72371c77851Sthreedeyes 	bigtime_t latency = system_time() - begin;
72471c77851Sthreedeyes 
72571c77851Sthreedeyes 	buffer->Recycle();
72671c77851Sthreedeyes 	delete test_group;
72771c77851Sthreedeyes 
72871c77851Sthreedeyes 	InitFilter();
72971c77851Sthreedeyes 
73071c77851Sthreedeyes 	return latency;
73171c77851Sthreedeyes }
73271c77851Sthreedeyes 
733*56bc38ceSPhilippe Saint-Pierre 
73471c77851Sthreedeyes void
73571c77851Sthreedeyes EqualizerNode::FilterBuffer(BBuffer* buffer)
73671c77851Sthreedeyes {
737*56bc38ceSPhilippe Saint-Pierre 	uint32 m_frameSize = (fFormat.u.raw_audio.format & 0x0f)
738*56bc38ceSPhilippe Saint-Pierre 		* fFormat.u.raw_audio.channel_count;
73971c77851Sthreedeyes 	uint32 samples = buffer->Header()->size_used / m_frameSize;
74071c77851Sthreedeyes 	uint32 channels = fFormat.u.raw_audio.channel_count;
741*56bc38ceSPhilippe Saint-Pierre 	if (fMute != 0)
74271c77851Sthreedeyes 		memset(buffer->Data(), 0, buffer->Header()->size_used);
743*56bc38ceSPhilippe Saint-Pierre 	else if (fByPass == 0)
74471c77851Sthreedeyes 		fEqualizer.ProcessBuffer((float*)buffer->Data(), samples * channels);
74571c77851Sthreedeyes }
746