ParameterWeb state is now saved and restored for each node.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3130 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval
2003-05-02 16:26:53 +00:00
parent 79441319f9
commit c8093d3c8d
5 changed files with 146 additions and 33 deletions
@@ -34,6 +34,7 @@
#include <Path.h>
#include <Directory.h>
#include <Entry.h>
#include <FindDirectory.h>
#include "MultiAudioNode.h"
#include "MultiAudioAddOn.h"
@@ -45,6 +46,8 @@
#include "debug.h"
#define MULTI_SAVE
// instantiation function
extern "C" _EXPORT BMediaAddOn * make_media_addon(image_id image) {
CALLED();
@@ -62,7 +65,8 @@ MultiAudioAddOn::~MultiAudioAddOn()
void *device = NULL;
for ( int32 i = 0; (device = fDevices.ItemAt(i)); i++ )
delete device;
SaveSettings();
}
MultiAudioAddOn::MultiAudioAddOn(image_id image) :
@@ -74,6 +78,8 @@ MultiAudioAddOn::MultiAudioAddOn(image_id image) :
if(RecursiveScan("/dev/audio/multi/")!=B_OK)
return;
LoadSettings();
fInitCheckStatus = B_OK;
}
@@ -135,6 +141,12 @@ BMediaNode * MultiAudioAddOn::InstantiateNodeFor(
return NULL;
}
#ifdef MULTI_SAVE
if(fSettings.FindMessage(device->MD.friendly_name, config)==B_OK) {
fSettings.RemoveData(device->MD.friendly_name);
}
#endif
MultiAudioNode * node
= new MultiAudioNode(this,
device->MD.friendly_name,
@@ -154,6 +166,20 @@ status_t
MultiAudioAddOn::GetConfigurationFor(BMediaNode * your_node, BMessage * into_message)
{
CALLED();
#ifdef MULTI_SAVE
if (into_message == 0) {
into_message = new BMessage();
MultiAudioNode * node = dynamic_cast<MultiAudioNode*>(your_node);
if (node == 0) {
fprintf(stderr,"<- B_BAD_TYPE\n");
return B_BAD_TYPE;
}
if(node->GetConfigurationFor(into_message)==B_OK) {
fSettings.AddMessage(your_node->Name(), into_message);
}
return B_OK;
}
#endif
// currently never called by the media kit. Seems it is not implemented.
if (into_message == 0) {
fprintf(stderr,"<- B_BAD_VALUE\n");
@@ -215,4 +241,38 @@ MultiAudioAddOn::RecursiveScan(char* rootPath, BEntry *rootEntry = NULL)
}
return B_OK;
}
void
MultiAudioAddOn::SaveSettings(void)
{
CALLED();
BPath path;
if(find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) {
path.Append(SETTINGS_FILE);
BFile file(path.Path(),B_READ_WRITE|B_CREATE_FILE|B_ERASE_FILE);
if(file.InitCheck()==B_OK)
fSettings.Flatten(&file);
}
}
void
MultiAudioAddOn::LoadSettings(void)
{
CALLED();
fSettings.MakeEmpty();
BPath path;
if(find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) {
path.Append(SETTINGS_FILE);
BFile file(path.Path(),B_READ_ONLY);
if((file.InitCheck()==B_OK)&&(fSettings.Unflatten(&file)==B_OK))
{
PRINT_OBJECT(fSettings);
} else {
PRINT(("Error unflattening settings file %s\n",path.Path()));
}
}
}
@@ -31,6 +31,8 @@
#include <MediaDefs.h>
#include <MediaAddOn.h>
#define SETTINGS_FILE "Media/multi_audio_settings"
class MultiAudioAddOn :
public BMediaAddOn
{
@@ -66,9 +68,13 @@ virtual status_t AutoStart(
private:
status_t RecursiveScan(char* path, BEntry *rootEntry = NULL);
void SaveSettings();
void LoadSettings();
status_t fInitCheckStatus;
BList fDevices;
BMessage fSettings; // settings loaded from settings directory
};
extern "C" _EXPORT BMediaAddOn *make_media_addon( image_id you );
@@ -198,34 +198,34 @@ status_t MultiAudioDevice::InitDriver()
return B_ERROR;
}
printf("Friendly name:\t%s\nVendor:\t\t%s\n",
MD.friendly_name,MD.vendor_info);
printf("%ld outputs\t%ld inputs\n%ld out busses\t%ld in busses\n",
PRINT(("Friendly name:\t%s\nVendor:\t\t%s\n",
MD.friendly_name,MD.vendor_info));
PRINT(("%ld outputs\t%ld inputs\n%ld out busses\t%ld in busses\n",
MD.output_channel_count,MD.input_channel_count,
MD.output_bus_channel_count,MD.input_bus_channel_count);
printf("\nChannels\n"
"ID\tKind\tDesig\tConnectors\n");
MD.output_bus_channel_count,MD.input_bus_channel_count));
PRINT(("\nChannels\n"
"ID\tKind\tDesig\tConnectors\n"));
for (i = 0 ; i < (MD.output_channel_count + MD.input_channel_count); i++)
{
printf("%ld\t%d\t0x%lx\t0x%lx\n",MD.channels[i].channel_id,
PRINT(("%ld\t%d\t0x%lx\t0x%lx\n",MD.channels[i].channel_id,
MD.channels[i].kind,
MD.channels[i].designations,
MD.channels[i].connectors);
MD.channels[i].connectors));
}
printf("\n");
PRINT(("\n"));
printf("Output rates\t\t0x%lx\n",MD.output_rates);
printf("Input rates\t\t0x%lx\n",MD.input_rates);
printf("Max CVSR\t\t%.0f\n",MD.max_cvsr_rate);
printf("Min CVSR\t\t%.0f\n",MD.min_cvsr_rate);
printf("Output formats\t\t0x%lx\n",MD.output_formats);
printf("Input formats\t\t0x%lx\n",MD.input_formats);
printf("Lock sources\t\t0x%lx\n",MD.lock_sources);
printf("Timecode sources\t0x%lx\n",MD.timecode_sources);
printf("Interface flags\t\t0x%lx\n",MD.interface_flags);
printf("Control panel string:\t\t%s\n",MD.control_panel);
printf("\n");
PRINT(("Output rates\t\t0x%lx\n",MD.output_rates));
PRINT(("Input rates\t\t0x%lx\n",MD.input_rates));
PRINT(("Max CVSR\t\t%.0f\n",MD.max_cvsr_rate));
PRINT(("Min CVSR\t\t%.0f\n",MD.min_cvsr_rate));
PRINT(("Output formats\t\t0x%lx\n",MD.output_formats));
PRINT(("Input formats\t\t0x%lx\n",MD.input_formats));
PRINT(("Lock sources\t\t0x%lx\n",MD.lock_sources));
PRINT(("Timecode sources\t0x%lx\n",MD.timecode_sources));
PRINT(("Interface flags\t\t0x%lx\n",MD.interface_flags));
PRINT(("Control panel string:\t\t%s\n",MD.control_panel));
PRINT(("\n"));
num_outputs = MD.output_channel_count;
num_inputs = MD.input_channel_count;
@@ -96,10 +96,12 @@ node_output::~node_output()
MultiAudioNode::~MultiAudioNode(void)
{
CALLED();
fAddOn->GetConfigurationFor(this, NULL);
StopThread();
BMediaEventLooper::Quit();
fWeb = NULL;
fWeb = NULL;
}
MultiAudioNode::MultiAudioNode(BMediaAddOn *addon, char* name, MultiAudioDevice *device,
@@ -112,7 +114,8 @@ MultiAudioNode::MultiAudioNode(BMediaAddOn *addon, char* name, MultiAudioDevice
fThread(-1),
fDevice(device),
fTimeSourceStarted(false),
fWeb(NULL)
fWeb(NULL),
fConfig(*config)
{
CALLED();
fInitCheckStatus = B_NO_INIT;
@@ -138,7 +141,7 @@ MultiAudioNode::MultiAudioNode(BMediaAddOn *addon, char* name, MultiAudioDevice
* (fPreferredFormat.u.raw_audio.format & media_raw_audio_format::B_AUDIO_SIZE_MASK)
* fPreferredFormat.u.raw_audio.channel_count;
config->PrintToStream();
PRINT_OBJECT(config);
fInitCheckStatus = B_OK;
}
@@ -212,10 +215,10 @@ void MultiAudioNode::NodeRegistered(void)
!(fDevice->MD.channels[i].designations & B_CHANNEL_SURROUND_BUS)))
) {
PRINT(("NodeRegistered() : creating an input for %i\n", i));
printf("%ld\t%d\t0x%lx\t0x%lx\n",fDevice->MD.channels[i].channel_id,
PRINT(("%ld\t%d\t0x%lx\t0x%lx\n",fDevice->MD.channels[i].channel_id,
fDevice->MD.channels[i].kind,
fDevice->MD.channels[i].designations,
fDevice->MD.channels[i].connectors);
fDevice->MD.channels[i].connectors));
media_input *input = new media_input;
@@ -258,10 +261,10 @@ void MultiAudioNode::NodeRegistered(void)
!(fDevice->MD.channels[i].designations & B_CHANNEL_SURROUND_BUS)))
) {
PRINT(("NodeRegistered() : creating an output for %i\n", i));
printf("%ld\t%d\t0x%lx\t0x%lx\n",fDevice->MD.channels[i].channel_id,
PRINT(("%ld\t%d\t0x%lx\t0x%lx\n",fDevice->MD.channels[i].channel_id,
fDevice->MD.channels[i].kind,
fDevice->MD.channels[i].designations,
fDevice->MD.channels[i].connectors);
fDevice->MD.channels[i].connectors));
media_output *output = new media_output;
@@ -291,6 +294,16 @@ void MultiAudioNode::NodeRegistered(void)
fWeb = MakeParameterWeb();
SetParameterWeb(fWeb);
/* apply configuration */
int32 index = 0;
int32 parameterID = 0;
const void *data;
ssize_t size;
while(fConfig.FindInt32("parameterID", index, &parameterID) == B_OK) {
if(fConfig.FindData("parameterData", B_RAW_TYPE, index, &data, &size) == B_OK)
SetParameterValue(parameterID, TimeSource()->Now(), data, size);
index++;
}
}
status_t MultiAudioNode::RequestCompleted(const media_request_info &info)
@@ -805,10 +818,10 @@ MultiAudioNode::Connect(status_t error, const media_source& source, const media_
// Do so, then make sure we get our events early enough.
media_node_id id;
FindLatencyFor(channel->fOutput.destination, &fLatency, &id);
fprintf(stderr, "\tdownstream latency = %Ld\n", fLatency);
PRINT(("\tdownstream latency = %Ld\n", fLatency));
fInternalLatency = 50LL;
fprintf(stderr, "\tbuffer-filling took %Ld usec on this machine\n", fInternalLatency);
PRINT(("\tbuffer-filling took %Ld usec on this machine\n", fInternalLatency));
//SetEventLatency(fLatency + fInternalLatency);
// reset our buffer duration, etc. to avoid later calculations
@@ -1338,7 +1351,7 @@ MultiAudioNode::MakeParameterWeb()
ProcessGroup(child, i, nb);
}
}
return web;
}
@@ -1857,7 +1870,39 @@ status_t
MultiAudioNode::GetConfigurationFor(BMessage * into_message)
{
CALLED();
into_message->AddString("name", Name());
BParameter *parameter = NULL;
void *buffer;
size_t size = 128;
bigtime_t last_change;
status_t err;
buffer = malloc(size);
for(int32 i=0; i<fWeb->CountParameters(); i++) {
parameter = fWeb->ParameterAt(i);
if(parameter->Type() != BParameter::B_CONTINUOUS_PARAMETER
&& parameter->Type() != BParameter::B_DISCRETE_PARAMETER)
continue;
PRINT(("getting parameter %i\n", parameter->ID()));
size = 128;
while((err = GetParameterValue(parameter->ID(), &last_change, buffer, &size))==B_NO_MEMORY) {
size += 128;
free(buffer);
buffer = malloc(size);
}
if(err == B_OK && size > 0) {
into_message->AddInt32("parameterID", parameter->ID());
into_message->AddData("parameterData", B_RAW_TYPE, buffer, size, false);
} else {
PRINT(("parameter err : %s\n", strerror(err)));
}
}
PRINT_OBJECT(into_message);
return B_OK;
}
@@ -387,6 +387,8 @@ private:
bool fTimeSourceStarted;
BParameterWeb *fWeb;
BMessage fConfig;
};
#endif /* _MULTIAUDIONODE_H */