master ohmu/fastfetch-openbsd / src / detection / sound / sound_haiku.cpp
ohmu  ·  2026-10-15
 1extern "C" {
 2#include "sound.h"
 3#include "common/strutil.h"
 4}
 5#include <MediaAddOn.h>
 6#include <MediaNode.h>
 7#include <MediaRoster.h>
 8#include <ParameterWeb.h>
 9
10const char* ffDetectSound([[maybe_unused]] FFSoundOptions* options, FFlist* devices /* List of FFSoundDevice */) {
11    BMediaRoster* roster = BMediaRoster::Roster();
12    media_node mediaNode;
13    live_node_info liveInfo;
14    dormant_node_info dormantInfo;
15
16    if (roster->GetAudioOutput(&mediaNode) != B_OK) {
17        return nullptr;
18    }
19
20    FFSoundDevice* device = FF_LIST_ADD(FFSoundDevice, *devices);
21    ffStrbufInit(&device->identifier);
22    if (roster->GetDormantNodeFor(mediaNode, &dormantInfo) == B_OK) {
23        ffStrbufAppendS(&device->identifier, dormantInfo.name);
24    }
25    ffStrbufInit(&device->name);
26    if (roster->GetLiveNodeInfo(mediaNode, &liveInfo) == B_OK) {
27        ffStrbufAppendS(&device->name, liveInfo.name);
28        ffStrbufTrimRightSpace(&device->name);
29    }
30    ffStrbufInitStatic(&device->platformApi, "MediaKit");
31    // We'll check the Mixer actually
32    device->volume = 0;
33    device->type = (FFSoundType) (FF_SOUND_TYPE_ACTIVE | FF_SOUND_TYPE_MAIN);
34
35    roster->ReleaseNode(mediaNode);
36
37    media_node mixer;
38    if (roster->GetAudioMixer(&mixer) != B_OK) {
39        return nullptr;
40    }
41
42    BParameterWeb* web;
43    status_t status = roster->GetParameterWebFor(mixer, &web);
44    roster->ReleaseNode(mixer); // the web is all we need :-)
45    if (status != B_OK) {
46        return nullptr;
47    }
48
49    BContinuousParameter* gain = nullptr;
50    BParameter* mute = nullptr;
51    BParameter* parameter;
52    for (int32 index = 0; (parameter = web->ParameterAt(index)) != nullptr; index++) {
53        // assume the mute preceding master gain control
54        if (ffStrEquals(parameter->Kind(), B_MUTE)) {
55            mute = parameter;
56        }
57
58        if (ffStrEquals(parameter->Kind(), B_MASTER_GAIN)) {
59            // Can not use dynamic_cast due to fno-rtti
60            // gain = dynamic_cast<BContinuousParameter *>(parameter);
61            gain = (BContinuousParameter*) (parameter);
62            break;
63        }
64    }
65
66    if (gain == nullptr) {
67        return nullptr;
68    }
69
70    bigtime_t when;
71    size_t size;
72
73    if (mute) {
74        int32 isMute = false;
75        size = sizeof(isMute);
76        if (mute->GetValue(&isMute, &size, &when) == B_OK && isMute) {
77            return nullptr;
78        }
79    }
80
81    float volume = 0.0;
82    size = sizeof(volume);
83    if (gain->GetValue(&volume, &size, &when) == B_OK) {
84        device->volume = (uint8_t) (100 * (volume - gain->MinValue()) / (gain->MaxValue() - gain->MinValue()));
85    }
86
87    return nullptr;
88}