The audio mixer is now started automatically by the media kit.

It will connect itself to the default audio output.
Memory leaks removed.
Code cleanup.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3307 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper
2003-05-24 23:52:34 +00:00
parent c9088353af
commit c9c07d8183
2 changed files with 148 additions and 48 deletions
@@ -1,13 +1,20 @@
// MixerAddOn.cpp // MixerAddOn.cpp
// //
// David Shipman, 2002 // David Shipman, 2002
// allows AudioMixer to be used as an addon // Marcus Overhagen, 2003
// //
// Allows AudioMixer to be used as an addon.
// The add-on will request to be auto-started,
// if this happens, it will try to connect
// itself to the default audio output.
#include <MediaRoster.h>
#include <MediaNode.h>
#include <cstring>
#include <cstdio>
#include "AudioMixer.h" #include "AudioMixer.h"
#include "MixerAddOn.h" #include "MixerAddOn.h"
#include <cstring>
#include <cstdlib>
// instantiation function // instantiation function
extern "C" _EXPORT BMediaAddOn* make_media_addon(image_id image) { extern "C" _EXPORT BMediaAddOn* make_media_addon(image_id image) {
@@ -18,66 +25,153 @@ extern "C" _EXPORT BMediaAddOn* make_media_addon(image_id image) {
// ctor/dtor // ctor/dtor
// -------------------------------------------------------- // // -------------------------------------------------------- //
AudioMixerAddon::~AudioMixerAddon() {} AudioMixerAddon::AudioMixerAddon(image_id image)
AudioMixerAddon::AudioMixerAddon(image_id image) : : BMediaAddOn(image),
BMediaAddOn(image) {} fFormat(new media_format),
fInfo(new flavor_info)
// -------------------------------------------------------- // {
// BMediaAddOn impl // Init media_format
// -------------------------------------------------------- // memset(fFormat, 0, sizeof(*fFormat));
fFormat->type = B_MEDIA_RAW_AUDIO;
fFormat->u.raw_audio = media_raw_audio_format::wildcard;
status_t AudioMixerAddon::InitCheck( // Init flavor_info
const char** out_failure_text) { fInfo->internal_id = 0;
return B_OK;
}
int32 AudioMixerAddon::CountFlavors() {
return 1;
}
status_t AudioMixerAddon::GetFlavorAt(
int32 n,
const flavor_info** out_info) {
if(n)
return B_ERROR;
flavor_info* fInfo = new flavor_info;
fInfo->internal_id = n;
fInfo->name = "AudioMixer"; fInfo->name = "AudioMixer";
fInfo->info = "AudioMixer media addon"; fInfo->info = "AudioMixer media addon";
fInfo->kinds = B_BUFFER_PRODUCER | B_BUFFER_CONSUMER | B_SYSTEM_MIXER | B_CONTROLLABLE; fInfo->kinds = B_BUFFER_PRODUCER | B_BUFFER_CONSUMER | B_SYSTEM_MIXER | B_CONTROLLABLE;
fInfo->flavor_flags = 0; // 0 = global or local instantiation allowed, no restrictions fInfo->flavor_flags = 0; // 0 = global or local instantiation allowed, no restrictions
fInfo->possible_count = 0; // 0 = infinite fInfo->possible_count = 0; // 0 = infinite
media_format* fFormat = new media_format;
fFormat->type = B_MEDIA_RAW_AUDIO;
fFormat->u.raw_audio = media_raw_audio_format::wildcard;
fInfo->in_format_count = 1; fInfo->in_format_count = 1;
fInfo->in_formats = fFormat; fInfo->in_formats = fFormat;
fInfo->out_format_count = 1; fInfo->out_format_count = 1;
fInfo->out_formats = fFormat; fInfo->out_formats = fFormat;
}
AudioMixerAddon::~AudioMixerAddon()
{
delete fFormat;
delete fInfo;
}
// -------------------------------------------------------- //
// BMediaAddOn impl
// -------------------------------------------------------- //
status_t
AudioMixerAddon::InitCheck(const char** out_failure_text)
{
return B_OK;
}
int32
AudioMixerAddon::CountFlavors()
{
return 1;
}
status_t
AudioMixerAddon::GetFlavorAt(int32 n, const flavor_info** out_info)
{
// only the 0th flavor exists
if (n != 0)
return B_ERROR;
*out_info = fInfo; *out_info = fInfo;
return B_OK; return B_OK;
} }
BMediaNode* AudioMixerAddon::InstantiateNodeFor( BMediaNode *
const flavor_info* info, AudioMixerAddon::InstantiateNodeFor(const flavor_info* info, BMessage* config,
BMessage* config, status_t* out_error)
status_t* out_error) { {
return new AudioMixer(this);
return new AudioMixer(this);
} }
status_t AudioMixerAddon::GetConfigurationFor( status_t
BMediaNode* your_node, AudioMixerAddon::GetConfigurationFor(BMediaNode* your_node, BMessage* into_message)
BMessage* into_message) { {
// no config yet // no config yet
return B_ERROR; return B_ERROR;
} }
// end bool
AudioMixerAddon::WantsAutoStart()
{
// yes, please kick me
return true;
}
status_t
AudioMixerAddon::AutoStart(int in_index, BMediaNode ** out_node,
int32 * out_internal_id, bool * out_has_more)
{
*out_has_more = false;
if (in_index != 0)
return B_ERROR;
*out_internal_id = 0;
*out_node = new AudioMixer(this);
// The mixer has been created.
// We now try to connect it with the default audio output.
if (ConnectToOutput(*out_node) != B_OK) {
printf("AudioMixerAddon::AutoStart: failed to ConnectToOutput()\n");
// cleanup
// return B_ERROR;
}
return B_OK;
}
status_t
AudioMixerAddon::ConnectToOutput(BMediaNode *node)
{
BMediaRoster *roster;
media_node mixer;
media_node soundcard;
media_input input;
media_output output;
int32 count;
status_t rv;
roster = BMediaRoster::Roster();
mixer = node->Node();
// XXX this connects to *any* physical output, but not the default logical input
rv = roster->GetAudioOutput(&soundcard);
if (rv < B_OK) {
printf("AudioMixerAddon::AutoStart: failed to find soundcard (physical audio output)\n");
return B_ERROR;
}
// we now have the mixer and soundcard nodes,
// find a free input/output and connect them
rv = roster->GetFreeOutputsFor(mixer, &output, 1, &count, B_MEDIA_RAW_AUDIO);
if (rv < B_OK || count != 1) {
printf("AudioMixerAddon::AutoStart: can't find free mixer output\n");
return B_ERROR;
}
rv = roster->GetFreeInputsFor(soundcard, &input, 1, &count, B_MEDIA_RAW_AUDIO);
if (rv < B_OK || count != 1) {
printf("AudioMixerAddon::AutoStart: can't find free soundcard input\n");
return B_ERROR;
}
media_format format;
memset(&format, 0, sizeof(format));
format.type = B_MEDIA_RAW_AUDIO;
rv = roster->Connect(output.source, input.destination, &format, &output, &input);
if (rv < B_OK) {
printf("AudioMixerAddon::AutoStart: connect failed\n");
return B_ERROR;
}
return B_OK;
}
@@ -34,12 +34,18 @@ virtual status_t GetConfigurationFor(
BMediaNode * your_node, BMediaNode * your_node,
BMessage * into_message); BMessage * into_message);
virtual bool WantsAutoStart() { return false; } virtual bool WantsAutoStart();
virtual status_t AutoStart( virtual status_t AutoStart(
int in_count, int in_index,
BMediaNode ** out_node, BMediaNode ** out_node,
int32 * out_internal_id, int32 * out_internal_id,
bool * out_has_more) { return B_OK; } bool * out_has_more);
private:
status_t ConnectToOutput(BMediaNode *node);
private:
media_format *fFormat;
flavor_info *fInfo;
}; };
#endif /*__AudioMixerAddOn_H_*/ #endif /*__AudioMixerAddOn_H_*/