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:
@@ -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, ¶meterID) == 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 */
|
||||
|
||||
Reference in New Issue
Block a user