xref: /haiku/src/add-ons/media/media-add-ons/mixer/MixerAddOn.cpp (revision c9c07d8183bf77a940ac4033e24dc0c0e2719ecd)
100cffa1cSbeveloper // MixerAddOn.cpp
200cffa1cSbeveloper //
300cffa1cSbeveloper // David Shipman, 2002
4*c9c07d81Sbeveloper // Marcus Overhagen, 2003
500cffa1cSbeveloper //
6*c9c07d81Sbeveloper // Allows AudioMixer to be used as an addon.
7*c9c07d81Sbeveloper // The add-on will request to be auto-started,
8*c9c07d81Sbeveloper // if this happens, it will try to connect
9*c9c07d81Sbeveloper // itself to the default audio output.
10*c9c07d81Sbeveloper 
11*c9c07d81Sbeveloper #include <MediaRoster.h>
12*c9c07d81Sbeveloper #include <MediaNode.h>
13*c9c07d81Sbeveloper #include <cstring>
14*c9c07d81Sbeveloper #include <cstdio>
1500cffa1cSbeveloper 
1600cffa1cSbeveloper #include "AudioMixer.h"
1700cffa1cSbeveloper #include "MixerAddOn.h"
1800cffa1cSbeveloper 
1900cffa1cSbeveloper // instantiation function
2000cffa1cSbeveloper extern "C" _EXPORT BMediaAddOn* make_media_addon(image_id image) {
2100cffa1cSbeveloper 	return new AudioMixerAddon(image);
2200cffa1cSbeveloper }
2300cffa1cSbeveloper 
24ea83877fSbeveloper // ------------------------------------------------------- //
2500cffa1cSbeveloper // ctor/dtor
2600cffa1cSbeveloper // -------------------------------------------------------- //
2700cffa1cSbeveloper 
28*c9c07d81Sbeveloper AudioMixerAddon::AudioMixerAddon(image_id image)
29*c9c07d81Sbeveloper  :	BMediaAddOn(image),
30*c9c07d81Sbeveloper  	fFormat(new media_format),
31*c9c07d81Sbeveloper  	fInfo(new flavor_info)
32*c9c07d81Sbeveloper {
33*c9c07d81Sbeveloper 	// Init media_format
34*c9c07d81Sbeveloper 	memset(fFormat, 0, sizeof(*fFormat));
35*c9c07d81Sbeveloper 	fFormat->type = B_MEDIA_RAW_AUDIO;
36*c9c07d81Sbeveloper 	fFormat->u.raw_audio = media_raw_audio_format::wildcard;
3700cffa1cSbeveloper 
38*c9c07d81Sbeveloper 	// Init flavor_info
39*c9c07d81Sbeveloper 	fInfo->internal_id = 0;
40ea83877fSbeveloper 	fInfo->name = "AudioMixer";
4129372222Sbeveloper 	fInfo->info = "AudioMixer media addon";
42ea83877fSbeveloper 	fInfo->kinds = B_BUFFER_PRODUCER | B_BUFFER_CONSUMER | B_SYSTEM_MIXER | B_CONTROLLABLE;
4329625f76Sbeveloper 	fInfo->flavor_flags = 0;	// 0 = global or local instantiation allowed, no restrictions
4429625f76Sbeveloper 	fInfo->possible_count = 0;	// 0 = infinite
45ea83877fSbeveloper 	fInfo->in_format_count = 1;
46ea83877fSbeveloper 	fInfo->in_formats = fFormat;
47ea83877fSbeveloper 	fInfo->out_format_count = 1;
48ea83877fSbeveloper 	fInfo->out_formats = fFormat;
49*c9c07d81Sbeveloper }
50*c9c07d81Sbeveloper 
51*c9c07d81Sbeveloper AudioMixerAddon::~AudioMixerAddon()
52*c9c07d81Sbeveloper {
53*c9c07d81Sbeveloper 	delete fFormat;
54*c9c07d81Sbeveloper 	delete fInfo;
55*c9c07d81Sbeveloper }
56*c9c07d81Sbeveloper 
57*c9c07d81Sbeveloper // -------------------------------------------------------- //
58*c9c07d81Sbeveloper // BMediaAddOn impl
59*c9c07d81Sbeveloper // -------------------------------------------------------- //
60*c9c07d81Sbeveloper 
61*c9c07d81Sbeveloper status_t
62*c9c07d81Sbeveloper AudioMixerAddon::InitCheck(const char** out_failure_text)
63*c9c07d81Sbeveloper {
64*c9c07d81Sbeveloper 	return B_OK;
65*c9c07d81Sbeveloper }
66*c9c07d81Sbeveloper 
67*c9c07d81Sbeveloper int32
68*c9c07d81Sbeveloper AudioMixerAddon::CountFlavors()
69*c9c07d81Sbeveloper {
70*c9c07d81Sbeveloper 	return 1;
71*c9c07d81Sbeveloper }
72*c9c07d81Sbeveloper 
73*c9c07d81Sbeveloper status_t
74*c9c07d81Sbeveloper AudioMixerAddon::GetFlavorAt(int32 n, const flavor_info** out_info)
75*c9c07d81Sbeveloper {
76*c9c07d81Sbeveloper 	// only the 0th flavor exists
77*c9c07d81Sbeveloper 	if (n != 0)
78*c9c07d81Sbeveloper 		return B_ERROR;
7900cffa1cSbeveloper 
80ea83877fSbeveloper 	*out_info = fInfo;
8100cffa1cSbeveloper 	return B_OK;
8200cffa1cSbeveloper }
8300cffa1cSbeveloper 
84*c9c07d81Sbeveloper BMediaNode *
85*c9c07d81Sbeveloper AudioMixerAddon::InstantiateNodeFor(const flavor_info* info, BMessage* config,
86*c9c07d81Sbeveloper 									status_t* out_error)
87*c9c07d81Sbeveloper {
8800cffa1cSbeveloper 	return new AudioMixer(this);
8900cffa1cSbeveloper }
9000cffa1cSbeveloper 
91*c9c07d81Sbeveloper status_t
92*c9c07d81Sbeveloper AudioMixerAddon::GetConfigurationFor(BMediaNode* your_node,	BMessage* into_message)
93*c9c07d81Sbeveloper {
9400cffa1cSbeveloper 	// no config yet
95ea83877fSbeveloper 	return B_ERROR;
9600cffa1cSbeveloper }
9700cffa1cSbeveloper 
98*c9c07d81Sbeveloper bool
99*c9c07d81Sbeveloper AudioMixerAddon::WantsAutoStart()
100*c9c07d81Sbeveloper {
101*c9c07d81Sbeveloper 	// yes, please kick me
102*c9c07d81Sbeveloper 	return true;
103*c9c07d81Sbeveloper }
104*c9c07d81Sbeveloper 
105*c9c07d81Sbeveloper status_t
106*c9c07d81Sbeveloper AudioMixerAddon::AutoStart(int in_index, BMediaNode ** out_node,
107*c9c07d81Sbeveloper 						   int32 * out_internal_id,	bool * out_has_more)
108*c9c07d81Sbeveloper {
109*c9c07d81Sbeveloper 	*out_has_more = false;
110*c9c07d81Sbeveloper 
111*c9c07d81Sbeveloper 	if (in_index != 0)
112*c9c07d81Sbeveloper 		return B_ERROR;
113*c9c07d81Sbeveloper 
114*c9c07d81Sbeveloper 	*out_internal_id = 0;
115*c9c07d81Sbeveloper 	*out_node = new AudioMixer(this);
116*c9c07d81Sbeveloper 
117*c9c07d81Sbeveloper 	// The mixer has been created.
118*c9c07d81Sbeveloper 	// We now try to connect it with the default audio output.
119*c9c07d81Sbeveloper 
120*c9c07d81Sbeveloper 	if (ConnectToOutput(*out_node) != B_OK) {
121*c9c07d81Sbeveloper 		printf("AudioMixerAddon::AutoStart: failed to ConnectToOutput()\n");
122*c9c07d81Sbeveloper 		// cleanup
123*c9c07d81Sbeveloper 		// return B_ERROR;
124*c9c07d81Sbeveloper 	}
125*c9c07d81Sbeveloper 
126*c9c07d81Sbeveloper 	return B_OK;
127*c9c07d81Sbeveloper }
128*c9c07d81Sbeveloper 
129*c9c07d81Sbeveloper status_t
130*c9c07d81Sbeveloper AudioMixerAddon::ConnectToOutput(BMediaNode *node)
131*c9c07d81Sbeveloper {
132*c9c07d81Sbeveloper 	BMediaRoster 		*roster;
133*c9c07d81Sbeveloper 	media_node 			mixer;
134*c9c07d81Sbeveloper 	media_node 			soundcard;
135*c9c07d81Sbeveloper 	media_input 		input;
136*c9c07d81Sbeveloper 	media_output 		output;
137*c9c07d81Sbeveloper 	int32 				count;
138*c9c07d81Sbeveloper 	status_t 			rv;
139*c9c07d81Sbeveloper 
140*c9c07d81Sbeveloper 	roster = BMediaRoster::Roster();
141*c9c07d81Sbeveloper 	mixer = node->Node();
142*c9c07d81Sbeveloper 
143*c9c07d81Sbeveloper 	// XXX this connects to *any* physical output, but not the default logical input
144*c9c07d81Sbeveloper 
145*c9c07d81Sbeveloper 	rv = roster->GetAudioOutput(&soundcard);
146*c9c07d81Sbeveloper 	if (rv < B_OK) {
147*c9c07d81Sbeveloper 		printf("AudioMixerAddon::AutoStart: failed to find soundcard (physical audio output)\n");
148*c9c07d81Sbeveloper 		return B_ERROR;
149*c9c07d81Sbeveloper 	}
150*c9c07d81Sbeveloper 
151*c9c07d81Sbeveloper 	// we now have the mixer and soundcard nodes,
152*c9c07d81Sbeveloper 	// find a free input/output and connect them
153*c9c07d81Sbeveloper 
154*c9c07d81Sbeveloper 	rv = roster->GetFreeOutputsFor(mixer, &output, 1, &count, B_MEDIA_RAW_AUDIO);
155*c9c07d81Sbeveloper 	if (rv < B_OK || count != 1) {
156*c9c07d81Sbeveloper 		printf("AudioMixerAddon::AutoStart: can't find free mixer output\n");
157*c9c07d81Sbeveloper 		return B_ERROR;
158*c9c07d81Sbeveloper 	}
159*c9c07d81Sbeveloper 
160*c9c07d81Sbeveloper 	rv = roster->GetFreeInputsFor(soundcard, &input, 1, &count, B_MEDIA_RAW_AUDIO);
161*c9c07d81Sbeveloper 	if (rv < B_OK || count != 1) {
162*c9c07d81Sbeveloper 		printf("AudioMixerAddon::AutoStart: can't find free soundcard input\n");
163*c9c07d81Sbeveloper 		return B_ERROR;
164*c9c07d81Sbeveloper 	}
165*c9c07d81Sbeveloper 
166*c9c07d81Sbeveloper 	media_format format;
167*c9c07d81Sbeveloper 	memset(&format, 0, sizeof(format));
168*c9c07d81Sbeveloper 	format.type = B_MEDIA_RAW_AUDIO;
169*c9c07d81Sbeveloper 
170*c9c07d81Sbeveloper 	rv = roster->Connect(output.source, input.destination, &format, &output, &input);
171*c9c07d81Sbeveloper 	if (rv < B_OK) {
172*c9c07d81Sbeveloper 		printf("AudioMixerAddon::AutoStart: connect failed\n");
173*c9c07d81Sbeveloper 		return B_ERROR;
174*c9c07d81Sbeveloper 	}
175*c9c07d81Sbeveloper 
176*c9c07d81Sbeveloper 	return B_OK;
177*c9c07d81Sbeveloper }
178