* Implemented support for setting/getting the audio gain in the

MediaFilesManager; the client protocol implementation is still missing.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34564 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-12-08 18:49:54 +00:00
parent f0ab4adfc9
commit e3745f7643
3 changed files with 183 additions and 76 deletions
+162 -70
View File
@@ -1,5 +1,6 @@
/*
* Copyright 2003, Jérôme Duval. All rights reserved.
* Copyright 2009, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*/
@@ -30,20 +31,30 @@ MediaFilesManager::MediaFilesManager()
fSaveTimerRunner(NULL)
{
CALLED();
entry_ref ref;
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_BEEP, ref, false);
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_STARTUP, ref, false);
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_KEY_DOWN, ref, false);
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_KEY_REPEAT, ref, false);
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_KEY_UP, ref, false);
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_MOUSE_DOWN, ref, false);
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_MOUSE_UP, ref, false);
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_ACTIVATED, ref, false);
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_CLOSE, ref, false);
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_MINIMIZED, ref, false);
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_OPEN, ref, false);
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_RESTORED, ref, false);
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_ZOOMED, ref, false);
static const struct {
const char* type;
const char* item;
} kInitialItems[] = {
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_BEEP},
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_STARTUP},
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_KEY_DOWN},
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_KEY_REPEAT},
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_KEY_UP},
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_MOUSE_DOWN},
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_MOUSE_UP},
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_ACTIVATED},
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_CLOSE},
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_MINIMIZED},
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_OPEN},
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_RESTORED},
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_ZOOMED}
};
for (size_t i = 0; i < sizeof(kInitialItems) / sizeof(kInitialItems[0]);
i++) {
_SetItem(kInitialItems[i].type, kInitialItems[i].item);
}
_LoadState();
#if DEBUG >=3
@@ -69,23 +80,26 @@ MediaFilesManager::SaveState()
TypeMap::iterator iterator = fMap.begin();
for (; iterator != fMap.end(); iterator++) {
const BString& type = iterator->first;
FileMap& fileMap = iterator->second;
ItemMap& itemMap = iterator->second;
BMessage items;
status = items.AddString("type", type.String());
if (status != B_OK)
return status;
FileMap::iterator fileIterator = fileMap.begin();
for (; fileIterator != fileMap.end(); fileIterator++) {
const BString& item = fileIterator->first;
BPath path(&fileIterator->second);
ItemMap::iterator itemIterator = itemMap.begin();
for (; itemIterator != itemMap.end(); itemIterator++) {
const BString& item = itemIterator->first;
item_info& info = itemIterator->second;
status = items.AddString("item", item.String());
if (status == B_OK) {
BPath path(&info.ref);
status = items.AddString("path",
path.Path() ? path.Path() : "");
}
if (status == B_OK)
status = items.AddFloat("gain", info.gain);
if (status != B_OK)
return status;
}
@@ -115,16 +129,19 @@ MediaFilesManager::Dump()
TypeMap::iterator iterator = fMap.begin();
for (; iterator != fMap.end(); iterator++) {
const BString& type = iterator->first;
FileMap& fileMap = iterator->second;
ItemMap& itemMap = iterator->second;
FileMap::iterator fileIterator = fileMap.begin();
for (; fileIterator != fileMap.end(); fileIterator++) {
ItemMap::iterator fileIterator = itemMap.begin();
for (; fileIterator != itemMap.end(); fileIterator++) {
const BString& item = fileIterator->first;
BPath path(&fileIterator->second);
const item_info& info = fileIterator->second;
printf(" type \"%s\", item \"%s\", path \"%s\"\n",
BPath path(&info.ref);
printf(" type \"%s\", item \"%s\", path \"%s\", gain %g\n",
type.String(), item.String(),
path.InitCheck() == B_OK ? path.Path() : "INVALID");
path.InitCheck() == B_OK ? path.Path() : "INVALID",
info.gain);
}
}
@@ -178,8 +195,8 @@ MediaFilesManager::GetItemsArea(const char* type, int32& count)
return B_NAME_NOT_FOUND;
}
FileMap& fileMap = found->second;
count = fileMap.size();
ItemMap& itemMap = found->second;
count = itemMap.size();
size_t size = (count * B_MEDIA_NAME_LENGTH + B_PAGE_SIZE - 1)
& ~(B_PAGE_SIZE - 1);
@@ -194,8 +211,8 @@ MediaFilesManager::GetItemsArea(const char* type, int32& count)
return area;
}
FileMap::iterator iterator = fileMap.begin();
for (; iterator != fileMap.end();
ItemMap::iterator iterator = itemMap.begin();
for (; iterator != itemMap.end();
iterator++, start += B_MEDIA_NAME_LENGTH) {
const BString& item = iterator->first;
strncpy(start, item.String(), B_MEDIA_NAME_LENGTH);
@@ -212,59 +229,67 @@ MediaFilesManager::GetRefFor(const char* type, const char* item,
CALLED();
BAutolock _(this);
TypeMap::iterator found = fMap.find(BString(type));
if (found == fMap.end())
return B_NAME_NOT_FOUND;
item_info* info;
status_t status = _GetItem(type, item, info);
if (status == B_OK)
*_ref = &info->ref;
FileMap::iterator foundFile = found->second.find(item);
if (foundFile == found->second.end())
return B_NAME_NOT_FOUND;
*_ref = &foundFile->second;
return B_OK;
return status;
}
status_t
MediaFilesManager::SetRefFor(const char* _type, const char* _item,
const entry_ref& ref, bool save)
MediaFilesManager::GetAudioGainFor(const char* type, const char* item,
float* _gain)
{
CALLED();
TRACE("MediaFilesManager::SetRefFor %s %s\n", _type, _item);
BAutolock _(this);
BString type(_type);
type.Truncate(B_MEDIA_NAME_LENGTH);
BString item(_item);
item.Truncate(B_MEDIA_NAME_LENGTH);
item_info* info;
status_t status = _GetItem(type, item, info);
if (status == B_OK)
*_gain = info->gain;
return status;
}
status_t
MediaFilesManager::SetRefFor(const char* type, const char* item,
const entry_ref& ref)
{
CALLED();
TRACE("MediaFilesManager::SetRefFor %s %s\n", type, item);
BAutolock _(this);
try {
TypeMap::iterator found = fMap.find(type);
if (found == fMap.end()) {
// add new type
FileMap fileMap;
// TODO: For some reason, this does not work:
//found = fMap.insert(TypeMap::value_type(type, fileMap));
fMap[type] = fileMap;
found = fMap.find(type);
}
FileMap& fileMap = found->second;
fileMap[item] = ref;
} catch (std::bad_alloc& exception) {
return B_NO_MEMORY;
}
if (save)
status_t status = _SetItem(type, item, &ref);
if (status == B_OK)
_LaunchTimer();
return B_OK;
return status;
}
status_t
MediaFilesManager::InvalidateRefFor(const char* type, const char* item)
MediaFilesManager::SetAudioGainFor(const char* type, const char* item,
float gain)
{
CALLED();
TRACE("MediaFilesManager::SetAudioGainFor %s %s %g\n", type, item, gain);
BAutolock _(this);
status_t status = _SetItem(type, item, NULL, &gain);
if (status == B_OK)
_LaunchTimer();
return status;
}
status_t
MediaFilesManager::InvalidateItem(const char* type, const char* item)
{
CALLED();
BAutolock _(this);
@@ -273,10 +298,8 @@ MediaFilesManager::InvalidateRefFor(const char* type, const char* item)
if (found == fMap.end())
return B_NAME_NOT_FOUND;
FileMap& fileMap = found->second;
entry_ref emptyRef;
fileMap[item] = emptyRef;
ItemMap& itemMap = found->second;
itemMap[item] = item_info();
_LaunchTimer();
return B_OK;
@@ -343,6 +366,71 @@ MediaFilesManager::_LaunchTimer()
}
/*! You need to have the manager locked when calling this method.
*/
status_t
MediaFilesManager::_GetItem(const char* type, const char* item,
item_info*& info)
{
ASSERT(IsLocked());
TypeMap::iterator found = fMap.find(type);
if (found == fMap.end())
return B_NAME_NOT_FOUND;
ItemMap::iterator foundFile = found->second.find(item);
if (foundFile == found->second.end())
return B_NAME_NOT_FOUND;
info = &foundFile->second;
return B_OK;
}
/*! You need to have the manager locked when calling this method after
launch.
*/
status_t
MediaFilesManager::_SetItem(const char* _type, const char* _item,
const entry_ref* ref, const float* gain)
{
CALLED();
TRACE("MediaFilesManager::_SetItem(%s, %s)\n", _type, _item);
BString type(_type);
type.Truncate(B_MEDIA_NAME_LENGTH);
BString item(_item);
item.Truncate(B_MEDIA_NAME_LENGTH);
try {
TypeMap::iterator found = fMap.find(type);
if (found == fMap.end()) {
// add new type
ItemMap itemMap;
// TODO: For some reason, this does not work:
//found = fMap.insert(TypeMap::value_type(type, itemMap));
fMap[type] = itemMap;
found = fMap.find(type);
}
ItemMap& itemMap = found->second;
item_info info = itemMap[item];
// only update what we've got
if (gain != NULL)
info.gain = *gain;
if (ref != NULL)
info.ref = *ref;
itemMap[item] = info;
} catch (std::bad_alloc& exception) {
return B_NO_MEMORY;
}
return B_OK;
}
status_t
MediaFilesManager::_OpenSettingsFile(BFile& file, int mode)
{
@@ -397,11 +485,15 @@ MediaFilesManager::_LoadState()
if (items.FindString("path", j, &path) != B_OK)
return B_BAD_DATA;
float gain;
if (items.FindFloat("gain", j, &gain) != B_OK)
gain = 1.0f;
entry_ref ref;
get_ref_for_path(path, &ref);
// it's okay for this to fail
SetRefFor(type, item, ref, false);
_SetItem(type, item, &ref, &gain);
}
}
+20 -5
View File
@@ -32,9 +32,13 @@ public:
status_t GetRefFor(const char* type, const char* item,
entry_ref** _ref);
status_t GetAudioGainFor(const char* type,
const char* item, float* _gain);
status_t SetRefFor(const char* type, const char* item,
const entry_ref& ref, bool save = true);
status_t InvalidateRefFor(const char* type,
const entry_ref& ref);
status_t SetAudioGainFor(const char* type,
const char* item, float gain);
status_t InvalidateItem(const char* type,
const char* item);
status_t RemoveItem(const char* type, const char* item);
@@ -43,14 +47,25 @@ public:
void HandleAddSystemBeepEvent(BMessage* message);
private:
struct item_info {
item_info() : gain(1.0f) {}
entry_ref ref;
float gain;
};
void _LaunchTimer();
status_t _GetItem(const char* type, const char* item,
item_info*& info);
status_t _SetItem(const char* type, const char* item,
const entry_ref* ref = NULL,
const float* gain = NULL);
status_t _OpenSettingsFile(BFile& file, int mode);
status_t _LoadState();
private:
// for each type, the map contains a map of item/entry_ref
typedef std::map<BString, entry_ref> FileMap;
typedef std::map<BString, FileMap> TypeMap;
typedef std::map<BString, item_info> ItemMap;
typedef std::map<BString, ItemMap> TypeMap;
TypeMap fMap;
BMessageRunner* fSaveTimerRunner;
+1 -1
View File
@@ -810,7 +810,7 @@ ServerApp::_HandleMessage(int32 code, void* data, size_t size)
= reinterpret_cast<const server_remove_ref_for_request*>(data);
server_remove_ref_for_reply reply;
status_t status = gMediaFilesManager->InvalidateRefFor(
status_t status = gMediaFilesManager->InvalidateItem(
request->type, request->item);
request->SendReply(status, &reply, sizeof(reply));
break;