summaryrefslogtreecommitdiffstats
path: root/HAL-afb
diff options
context:
space:
mode:
authorfulup <fulup.arfoll@iot.bzh>2017-08-03 12:00:41 +0200
committerfulup <fulup.arfoll@iot.bzh>2017-08-03 12:00:41 +0200
commit070ccac33d65c651c972dfab9c6148e43d8d5d8e (patch)
tree07b79faec9bcaacf14dcc7f8ed08cacf35557e7d /HAL-afb
parent39384e722d9fd7d162012b682aed41b35d16d003 (diff)
Initial Working Version on Alsa Policy-Policy-Hook
Diffstat (limited to 'HAL-afb')
-rw-r--r--HAL-afb/HAL-interface/hal-interface.c619
-rw-r--r--HAL-afb/HAL-interface/hal-interface.h72
-rw-r--r--HAL-afb/HAL-interface/hal-volramp.c161
-rw-r--r--HAL-afb/HAL-interface/hal-volume.c126
-rw-r--r--HAL-afb/HAL-plugin/CMakeLists.txt55
-rw-r--r--HAL-afb/HAL-plugin/HalPlug.h92
-rw-r--r--HAL-afb/HAL-plugin/HalPlugCb.c64
-rw-r--r--HAL-afb/HAL-plugin/HalPlugCtl.c423
-rw-r--r--HAL-afb/HAL-plugin/README.md44
-rw-r--r--HAL-afb/HDA-intel/IntelHdaHAL.c60
-rw-r--r--HAL-afb/Jabra-Solemate/CMakeLists.txt (renamed from HAL-afb/Unicens-USB/CMakeLists.txt)6
-rw-r--r--HAL-afb/Jabra-Solemate/JabraUsbHAL.c123
-rw-r--r--HAL-afb/Scarlett-Focusrite/CMakeLists.txt2
-rw-r--r--HAL-afb/Scarlett-Focusrite/ScarlettUsbHAL.c4
-rw-r--r--HAL-afb/Unicens-USB/UnicensHAL.c62
-rw-r--r--HAL-afb/Unicens-USB/UnicensVol.c37
16 files changed, 650 insertions, 1300 deletions
diff --git a/HAL-afb/HAL-interface/hal-interface.c b/HAL-afb/HAL-interface/hal-interface.c
index cba10d7..4d86504 100644
--- a/HAL-afb/HAL-interface/hal-interface.c
+++ b/HAL-afb/HAL-interface/hal-interface.c
@@ -25,40 +25,12 @@
alsaHalSndCardT *halSndCard;
-STATIC const char *halCtlsLabels[] = {
-
- [Master_Playback_Volume] = "Master_Playback_Volume",
- [Master_OnOff_Switch] = "Master_OnOff_Switch",
- [Master_Playback_Ramp]= "Master_Playback_Ramp",
- [PCM_Playback_Volume] = "PCM_Playback_Volume",
- [PCM_Playback_Switch] = "PCM_Playback_Switch",
- [Capture_Volume] = "Capture_Volume",
-
- [Vol_Ramp] = "Volume_Ramp",
- [Vol_Ramp_Set_Mode] = "Volume_Ramp_Mode",
- [Vol_Ramp_Set_Delay] = "Volume_Ramp_Delay",
- [Vol_Ramp_Set_Down] = "Volume_Ramp_Down",
- [Vol_Ramp_Set_Up] = "Volume_Ramp_Up",
- [Vol_Ramp_Set_Slave] = "Volume_Ramp_Slave",
-
- [EndHalCrlTag] = NULL
-};
-
-PUBLIC char *halVolRampModes[] = {
-
- [RAMP_VOL_NONE] = "None",
- [RAMP_VOL_NORMAL] = "Normal",
- [RAMP_VOL_SMOOTH] = "Smooth",
- [RAMP_VOL_EMERGENCY] = "Emergency",
-
- [EndHalVolMod] = NULL,
-
-};
// Force specific HAL to depend on ShareHalLib
-PUBLIC char* SharedHalLibVersion="1.0";
-
+PUBLIC char* SharedHalLibVersion = "1.0";
+
// Subscribe to AudioBinding events
+
STATIC void halSubscribe(afb_req request) {
const char *devidJ = afb_req_value(request, "devid");
if (devidJ == NULL) {
@@ -67,194 +39,200 @@ STATIC void halSubscribe(afb_req request) {
}
// Map HAL ctlName to ctlLabel
-STATIC int halCtlStringToIndex (const char* label) {
- alsaHalMapT *halCtls= halSndCard->ctls;
- for (int idx = 0; halCtls[idx].tag != EndHalCrlTag; idx++) {
- if (halCtls[idx].label && !strcmp (halCtls[idx].label, label)) return idx;
+STATIC int halCtlStringToIndex(const char* label) {
+ alsaHalMapT *halCtls = halSndCard->ctls;
+
+ for (int idx = 0; halCtls[idx].tag != EndHalCrlTag; idx++) {
+ if (halCtls[idx].label && !strcmp(halCtls[idx].label, label)) return idx;
}
-
+
// not found
return -1;
}
-STATIC int halCtlTagToIndex (halCtlsEnumT tag) {
- alsaHalMapT *halCtls= halSndCard->ctls;
+STATIC int halCtlTagToIndex(halCtlsTagT tag) {
+ alsaHalMapT *halCtls = halSndCard->ctls;
- for (int idx = 0; halCtls[idx].tag != EndHalCrlTag; idx++) {
- if (halCtls[idx].tag == tag) return idx;
+ for (int idx = 0; halCtls[idx].tag != EndHalCrlTag; idx++) {
+ if (halCtls[idx].tag == tag) return idx;
}
-
+
// not found
return -1;
}
// Return ALL HAL snd controls
+
PUBLIC void halListCtls(afb_req request) {
- alsaHalMapT *halCtls= halSndCard->ctls;
+ alsaHalMapT *halCtls = halSndCard->ctls;
json_object *ctlsHalJ = json_object_new_array();
-
+
for (int idx = 0; halCtls[idx].ctl.numid; idx++) {
json_object *ctlHalJ = json_object_new_object();
-
- json_object_object_add(ctlHalJ, "label", json_object_new_string(halCtls[idx].label));
- json_object_object_add(ctlHalJ, "tag" , json_object_new_int(halCtls[idx].tag));
+
+ if (halCtls[idx].label) json_object_object_add(ctlHalJ, "label", json_object_new_string(halCtls[idx].label));
+ else json_object_object_add(ctlHalJ, "label", json_object_new_string("HAL Label Not Set "));
+ json_object_object_add(ctlHalJ, "tag", json_object_new_int(halCtls[idx].tag));
json_object_object_add(ctlHalJ, "count", json_object_new_int(halCtls[idx].ctl.count));
-
- json_object_array_add (ctlsHalJ, ctlHalJ);
+
+ json_object_array_add(ctlsHalJ, ctlHalJ);
}
-
- afb_req_success (request, ctlsHalJ, NULL);
+
+ afb_req_success(request, ctlsHalJ, NULL);
}
-STATIC int halGetCtlIndex (afb_req request, json_object*ctlInJ) {
+STATIC int halGetCtlIndex(afb_req request, json_object*ctlInJ) {
json_object *tmpJ;
int tag, index, done;
// check 1st short command mode [tag1, tag2, ...]
- enum json_type jtype = json_object_get_type (ctlInJ);
+ enum json_type jtype = json_object_get_type(ctlInJ);
switch (jtype) {
- case json_type_array:
- tmpJ = json_object_array_get_idx (ctlInJ, 0);
+ case json_type_array:
+ tmpJ = json_object_array_get_idx(ctlInJ, 0);
tag = json_object_get_int(tmpJ);
- index = halCtlTagToIndex(tag);
+ index = halCtlTagToIndex(tag);
break;
-
- case json_type_int:
+
+ case json_type_int:
tag = json_object_get_int(ctlInJ);
- index = halCtlTagToIndex(tag);
+ index = halCtlTagToIndex(tag);
break;
-
+
case json_type_object:
- done = json_object_object_get_ex (ctlInJ, "tag" , &tmpJ);
+ done = json_object_object_get_ex(ctlInJ, "tag", &tmpJ);
if (done) {
tag = json_object_get_int(tmpJ);
- index = halCtlTagToIndex(tag);
+ index = halCtlTagToIndex(tag);
} else {
const char *label;
- done = json_object_object_get_ex (ctlInJ, "label" , &tmpJ);
+ done = json_object_object_get_ex(ctlInJ, "label", &tmpJ);
if (!done) goto OnErrorExit;
label = json_object_get_string(tmpJ);
index = halCtlStringToIndex(label);
}
break;
-
- default:
+
+ default:
goto OnErrorExit;
}
-
+
if (index < 0) goto OnErrorExit;
-
+
// return corresponding lowlevel numid to querylist
return index;
-
- OnErrorExit:
- afb_req_fail_f(request, "ctl-invalid", "No Label/Tag given ctl='%s'", json_object_get_string(ctlInJ));
- return -1;
-}
+OnErrorExit:
+ afb_req_fail_f(request, "ctl-invalid", "No Label/Tag given ctl='%s'", json_object_get_string(ctlInJ));
+ return -1;
+}
-STATIC int halCallAlsaSetCtls (json_object *ctlsOutJ) {
+STATIC int halCallAlsaSetCtls(json_object *ctlsOutJ) {
json_object *responseJ, *queryJ;
int err;
-
+
// Call now level CTL
queryJ = json_object_new_object();
- json_object_object_add(queryJ, "devid", json_object_new_string (halSndCard->devid));
+ json_object_object_add(queryJ, "devid", json_object_new_string(halSndCard->devid));
json_object_object_add(queryJ, "ctl", ctlsOutJ);
-
- err= afb_service_call_sync("alsacore", "setctl", queryJ, &responseJ);
- json_object_put (responseJ); // let's ignore response
-
+
+ err = afb_service_call_sync("alsacore", "setctl", queryJ, &responseJ);
+ json_object_put(responseJ); // let's ignore response
+
return err;
}
// retrieve a single HAL control from its tag.
-PUBLIC int halSetCtlByTag (halRampEnumT tag, int value) {
+
+PUBLIC int halSetCtlByTag(halRampEnumT tag, int value) {
json_object *ctlJ = json_object_new_array();
- alsaHalMapT *halCtls= halSndCard->ctls;
+ alsaHalMapT *halCtls = halSndCard->ctls;
int err, index;
-
- index = halCtlTagToIndex(tag);
+
+ index = halCtlTagToIndex(tag);
if (index < 0) goto OnErrorExit;
-
+
json_object_array_add(ctlJ, json_object_new_int(halCtls[index].ctl.numid));
- json_object_array_add(ctlJ, volumeNormalise (ACTION_SET, &halCtls[index].ctl, json_object_new_int(value)));
-
+ json_object_array_add(ctlJ, volumeNormalise(ACTION_SET, &halCtls[index].ctl, json_object_new_int(value)));
+
err = halCallAlsaSetCtls(ctlJ);
-
+
return err;
-
- OnErrorExit:
- return -1;
+
+OnErrorExit:
+ return -1;
}
// Translate high level control to low level and call lower layer
+
PUBLIC void halSetCtls(afb_req request) {
- alsaHalMapT *halCtls= halSndCard->ctls;
+ alsaHalMapT *halCtls = halSndCard->ctls;
int err, done, index;
json_object *ctlsInJ, *ctlsOutJ, *valuesJ;
// get query from request
ctlsInJ = afb_req_json(request);
-
+
switch (json_object_get_type(ctlsInJ)) {
- case json_type_object: {
+ case json_type_object:
+ {
ctlsOutJ = json_object_new_object();
-
+
// control is in literal form {tag=xxx, label=xxx, value=xxxx}
- index = halGetCtlIndex (request, ctlsInJ);
+ index = halGetCtlIndex(request, ctlsInJ);
if (index < 0) goto OnErrorExit;
-
- done= json_object_object_get_ex (ctlsInJ, "val" , &valuesJ);
+
+ done = json_object_object_get_ex(ctlsInJ, "val", &valuesJ);
if (!done) {
afb_req_fail_f(request, "ctl-invalid", "No val=[val1, ...] ctl='%s'", json_object_get_string(ctlsInJ));
- goto OnErrorExit;
+ goto OnErrorExit;
}
-
- json_object_object_add (ctlsOutJ, "id", json_object_new_int(halCtls[index].ctl.numid));
- json_object_object_add (ctlsOutJ,"val", volumeNormalise (ACTION_SET, &halCtls[index].ctl, valuesJ));
+
+ json_object_object_add(ctlsOutJ, "id", json_object_new_int(halCtls[index].ctl.numid));
+ json_object_object_add(ctlsOutJ, "val", volumeNormalise(ACTION_SET, &halCtls[index].ctl, valuesJ));
break;
}
-
- case json_type_array: {
+
+ case json_type_array:
+ {
ctlsOutJ = json_object_new_array();
-
- for (int idx= 0; idx < json_object_array_length (ctlsInJ); idx++) {
- json_object *ctlInJ = json_object_array_get_idx (ctlsInJ, idx);
- index= halGetCtlIndex (request, ctlInJ);
+
+ for (int idx = 0; idx < json_object_array_length(ctlsInJ); idx++) {
+ json_object *ctlInJ = json_object_array_get_idx(ctlsInJ, idx);
+ index = halGetCtlIndex(request, ctlInJ);
if (index < 0) goto OnErrorExit;
- done= json_object_object_get_ex (ctlInJ, "val" , &valuesJ);
+ done = json_object_object_get_ex(ctlInJ, "val", &valuesJ);
if (!done) {
afb_req_fail_f(request, "ctl-invalid", "No val=[val1, ...] ctl='%s'", json_object_get_string(ctlsInJ));
- goto OnErrorExit;
+ goto OnErrorExit;
}
// let's create alsa low level set control request
json_object *ctlOutJ = json_object_new_object();
- json_object_object_add (ctlOutJ, "id", json_object_new_int(halCtls[index].ctl.numid));
- json_object_object_add (ctlOutJ, "val", volumeNormalise (ACTION_SET, &halCtls[index].ctl, valuesJ));
-
- json_object_array_add (ctlsOutJ, ctlOutJ);
+ json_object_object_add(ctlOutJ, "id", json_object_new_int(halCtls[index].ctl.numid));
+ json_object_object_add(ctlOutJ, "val", volumeNormalise(ACTION_SET, &halCtls[index].ctl, valuesJ));
+
+ json_object_array_add(ctlsOutJ, ctlOutJ);
}
break;
}
-
+
default:
afb_req_fail_f(request, "ctl-invalid", "Not a valid JSON ctl='%s'", json_object_get_string(ctlsInJ));
- goto OnErrorExit;
+ goto OnErrorExit;
}
- err = halCallAlsaSetCtls (ctlsOutJ);
+ err = halCallAlsaSetCtls(ctlsOutJ);
if (err) {
afb_req_fail_f(request, "subcall:alsacore/setctl", "%s", json_object_get_string(ctlsOutJ));
- goto OnErrorExit;
+ goto OnErrorExit;
}
-
- afb_req_success (request, NULL, NULL);
+
+ afb_req_success(request, NULL, NULL);
return;
OnErrorExit:
@@ -262,8 +240,9 @@ OnErrorExit:
};
// Remap low level controls into HAL hight level ones
+
STATIC json_object *HalGetPrepareResponse(afb_req request, json_object *ctlsJ) {
- alsaHalMapT *halCtls= halSndCard->ctls;
+ alsaHalMapT *halCtls = halSndCard->ctls;
json_object *halResponseJ;
int length;
@@ -274,14 +253,14 @@ STATIC json_object *HalGetPrepareResponse(afb_req request, json_object *ctlsJ) {
length = json_object_array_length(ctlsJ);
break;
case json_type_object:
- halResponseJ=NULL;
+ halResponseJ = NULL;
length = 1;
break;
default:
afb_req_fail_f(request, "ctls-notarray", "Invalid Controls return from alsa/getcontrol ctlsJ=%s", json_object_get_string(ctlsJ));
goto OnErrorExit;
}
-
+
// loop on array and store values into client context
for (int idx = 0; idx < length; idx++) {
json_object *sndCtlJ, *valJ, *numidJ;
@@ -289,356 +268,358 @@ STATIC json_object *HalGetPrepareResponse(afb_req request, json_object *ctlsJ) {
// extract control from array if any
if (halResponseJ) sndCtlJ = json_object_array_get_idx(ctlsJ, idx);
- else sndCtlJ=ctlsJ;
-
- if (!json_object_object_get_ex(sndCtlJ, "id", &numidJ) || !json_object_object_get_ex(sndCtlJ, "val", &valJ)) {
+ else sndCtlJ = ctlsJ;
+
+ if (!json_object_object_get_ex(sndCtlJ, "id", &numidJ) || !json_object_object_get_ex(sndCtlJ, "val", &valJ)) {
afb_req_fail_f(request, "ctl-invalid", "Invalid Control return from alsa/getcontrol ctl=%s", json_object_get_string(sndCtlJ));
goto OnErrorExit;
}
-
+
// HAL and Business logic use the same AlsaMixerHal.h direct conversion
- numid= (halCtlsEnumT) json_object_get_int(numidJ);
+ numid = (halCtlsTagT) json_object_get_int(numidJ);
for (int idx = 0; halCtls[idx].ctl.numid; idx++) {
- if (halCtls[idx].ctl.numid == numid) {
+ if (halCtls[idx].ctl.numid == numid) {
// translate low level numid to HAL one and normalise values
json_object *halCtlJ = json_object_new_object();
json_object_object_add(halCtlJ, "label", json_object_new_string(halCtls[idx].label)); // idx+1 == HAL/NUMID
- json_object_object_add(halCtlJ, "tag" , json_object_new_int(halCtls[idx].tag)); // idx+1 == HAL/NUMID
- json_object_object_add(halCtlJ, "val" , volumeNormalise(ACTION_GET, &halCtls[idx].ctl, valJ));
-
+ json_object_object_add(halCtlJ, "tag", json_object_new_int(halCtls[idx].tag)); // idx+1 == HAL/NUMID
+ json_object_object_add(halCtlJ, "val", volumeNormalise(ACTION_GET, &halCtls[idx].ctl, valJ));
+
if (halResponseJ) json_object_array_add(halResponseJ, halCtlJ);
- else halResponseJ=halCtlJ;
-
+ else halResponseJ = halCtlJ;
+
break;
- }
+ }
}
- if ( halCtls[idx].ctl.numid == 0) {
+ if (halCtls[idx].ctl.numid == 0) {
afb_req_fail_f(request, "ctl-invalid", "Invalid Control numid=%d from alsa/getcontrol ctlJ=%s", numid, json_object_get_string(sndCtlJ));
goto OnErrorExit;
- }
+ }
}
return halResponseJ;
-
- OnErrorExit:
- return NULL;
-}
-
+OnErrorExit:
+ return NULL;
+}
-STATIC json_object *halCallAlsaGetCtls (json_object *ctlsOutJ) {
+STATIC json_object *halCallAlsaGetCtls(json_object *ctlsOutJ) {
json_object *responseJ, *queryJ;
int err, done;
-
+
// Call now level CTL
queryJ = json_object_new_object();
- json_object_object_add(queryJ, "devid", json_object_new_string (halSndCard->devid));
+ json_object_object_add(queryJ, "devid", json_object_new_string(halSndCard->devid));
json_object_object_add(queryJ, "ctl", ctlsOutJ);
- err= afb_service_call_sync("alsacore", "getctl", queryJ, &responseJ);
+ err = afb_service_call_sync("alsacore", "getctl", queryJ, &responseJ);
if (err) goto OnErrorExit;
-
+
// Let ignore info data if any and keep on response
- done = json_object_object_get_ex (responseJ, "response", &responseJ);
+ done = json_object_object_get_ex(responseJ, "response", &responseJ);
if (!done) goto OnErrorExit;
-
+
return responseJ;
-
- OnErrorExit:
- return NULL;
+
+OnErrorExit:
+ return NULL;
}
// retrieve a single HAL control from its tag.
-PUBLIC json_object *halGetCtlByTag (halRampEnumT tag) {
+
+PUBLIC json_object *halGetCtlByTag(halRampEnumT tag) {
json_object *responseJ, *valJ;
- alsaHalMapT *halCtls= halSndCard->ctls;
+ alsaHalMapT *halCtls = halSndCard->ctls;
int done, index;
-
- index = halCtlTagToIndex(tag);
+
+ index = halCtlTagToIndex(tag);
if (index < 0) goto OnErrorExit;
responseJ = halCallAlsaGetCtls(json_object_new_int(halCtls[index].ctl.numid));
-
+
done = json_object_object_get_ex(responseJ, "val", &valJ);
if (!done) goto OnErrorExit;
-
+
return volumeNormalise(ACTION_GET, &halCtls[index].ctl, valJ);
-
- OnErrorExit:
- return NULL;
+
+OnErrorExit:
+ return NULL;
}
// Translate high level control to low level and call lower layer
+
PUBLIC void halGetCtls(afb_req request) {
int index;
- alsaHalMapT *halCtls= halSndCard->ctls;
+ alsaHalMapT *halCtls = halSndCard->ctls;
json_object *ctlsInJ, *ctlsOutJ, *responseJ;
// get query from request
ctlsInJ = afb_req_json(request);
ctlsOutJ = json_object_new_array();
-
+
switch (json_object_get_type(ctlsInJ)) {
- case json_type_object: {
+ case json_type_object:
+ {
- index = halGetCtlIndex (request, ctlsInJ);
+ index = halGetCtlIndex(request, ctlsInJ);
if (index < 0) goto OnErrorExit;
- json_object_array_add (ctlsOutJ, json_object_new_int(halCtls[index].ctl.numid));
+ json_object_array_add(ctlsOutJ, json_object_new_int(halCtls[index].ctl.numid));
break;
}
-
- case json_type_array: {
-
- for (int idx= 0; idx < json_object_array_length (ctlsInJ); idx++) {
- json_object *ctlInJ = json_object_array_get_idx (ctlsInJ, idx);
- index= halGetCtlIndex (request, ctlInJ);
+
+ case json_type_array:
+ {
+
+ for (int idx = 0; idx < json_object_array_length(ctlsInJ); idx++) {
+ json_object *ctlInJ = json_object_array_get_idx(ctlsInJ, idx);
+ index = halGetCtlIndex(request, ctlInJ);
if (index < 0) goto OnErrorExit;
- json_object_array_add (ctlsOutJ, json_object_new_int(halCtls[index].ctl.numid));
+ json_object_array_add(ctlsOutJ, json_object_new_int(halCtls[index].ctl.numid));
}
break;
}
-
+
default:
afb_req_fail_f(request, "ctl-invalid", "Not a valid JSON ctl='%s'", json_object_get_string(ctlsInJ));
- goto OnErrorExit;
+ goto OnErrorExit;
}
// Call now level CTL
- responseJ = halCallAlsaGetCtls (ctlsOutJ);
+ responseJ = halCallAlsaGetCtls(ctlsOutJ);
if (!responseJ) {
afb_req_fail_f(request, "subcall:alsacore/getctl", "%s", json_object_get_string(responseJ));
- goto OnErrorExit;
+ goto OnErrorExit;
}
-
+
// map back low level response to HAL ctl with normalised values
- json_object *halResponse = HalGetPrepareResponse(request, responseJ);
+ json_object *halResponse = HalGetPrepareResponse(request, responseJ);
if (!halResponse) goto OnErrorExit;
-
- afb_req_success (request, halResponse, NULL);
+
+ afb_req_success(request, halResponse, NULL);
return;
OnErrorExit:
return;
};
-
-STATIC int UpdateOneSndCtl (alsaHalCtlMapT *ctl, json_object *sndCtlJ) {
+STATIC int UpdateOneSndCtl(alsaHalCtlMapT *ctl, json_object *sndCtlJ) {
json_object *tmpJ, *ctlJ;
- json_object_object_get_ex (sndCtlJ, "name" , &tmpJ);
- ctl->name = (char*)json_object_get_string(tmpJ);
-
- json_object_object_get_ex (sndCtlJ, "id" , &tmpJ);
- ctl->numid = json_object_get_int(tmpJ);
-
+ json_object_object_get_ex(sndCtlJ, "name", &tmpJ);
+ ctl->name = (char*) json_object_get_string(tmpJ);
+
+ json_object_object_get_ex(sndCtlJ, "id", &tmpJ);
+ ctl->numid = json_object_get_int(tmpJ);
+
// make sure we face a valid Alsa Low level ctl
- if (!json_object_object_get_ex (sndCtlJ, "ctl" , &ctlJ)) goto OnErrorExit;
-
- json_object_object_get_ex (ctlJ, "min" , &tmpJ);
- ctl->minval = json_object_get_int(tmpJ);
-
- json_object_object_get_ex (ctlJ, "max" , &tmpJ);
- ctl->maxval = json_object_get_int(tmpJ);
-
- json_object_object_get_ex (ctlJ, "step" , &tmpJ);
- ctl->step = json_object_get_int(tmpJ);
-
- json_object_object_get_ex (ctlJ, "count" , &tmpJ);
- ctl->count = json_object_get_int(tmpJ);
-
- json_object_object_get_ex (ctlJ, "type" , &tmpJ);
- ctl->type = (snd_ctl_elem_type_t)json_object_get_int(tmpJ);
-
+ if (!json_object_object_get_ex(sndCtlJ, "ctl", &ctlJ)) goto OnErrorExit;
+
+ json_object_object_get_ex(ctlJ, "min", &tmpJ);
+ ctl->minval = json_object_get_int(tmpJ);
+
+ json_object_object_get_ex(ctlJ, "max", &tmpJ);
+ ctl->maxval = json_object_get_int(tmpJ);
+
+ json_object_object_get_ex(ctlJ, "step", &tmpJ);
+ ctl->step = json_object_get_int(tmpJ);
+
+ json_object_object_get_ex(ctlJ, "count", &tmpJ);
+ ctl->count = json_object_get_int(tmpJ);
+
+ json_object_object_get_ex(ctlJ, "type", &tmpJ);
+ ctl->type = (snd_ctl_elem_type_t) json_object_get_int(tmpJ);
+
// process dbscale TLV if any
- if (json_object_object_get_ex (sndCtlJ, "tlv" , &tmpJ)) {
+ if (json_object_object_get_ex(sndCtlJ, "tlv", &tmpJ)) {
json_object *dbscaleJ;
-
- if (!json_object_object_get_ex (tmpJ, "dbscale" , &dbscaleJ)) {
+
+ if (!json_object_object_get_ex(tmpJ, "dbscale", &dbscaleJ)) {
AFB_WARNING("TLV found but not DBscale attached ctl name=%s numid=%d", ctl->name, ctl->numid);
} else {
- ctl->dbscale = malloc (sizeof (alsaHalDBscaleT));
-
- json_object_object_get_ex (dbscaleJ, "min" , &tmpJ);
- ctl->dbscale->min = (snd_ctl_elem_type_t)json_object_get_int(tmpJ);
-
- json_object_object_get_ex (dbscaleJ, "max" , &tmpJ);
- ctl->dbscale->max = (snd_ctl_elem_type_t)json_object_get_int(tmpJ);
-
- json_object_object_get_ex (dbscaleJ, "step" , &tmpJ);
- ctl->dbscale->step = (snd_ctl_elem_type_t)json_object_get_int(tmpJ);
-
- json_object_object_get_ex (dbscaleJ, "mute" , &tmpJ);
- ctl->dbscale->mute = (snd_ctl_elem_type_t)json_object_get_int(tmpJ);
+ ctl->dbscale = malloc(sizeof (alsaHalDBscaleT));
+
+ json_object_object_get_ex(dbscaleJ, "min", &tmpJ);
+ ctl->dbscale->min = (snd_ctl_elem_type_t) json_object_get_int(tmpJ);
+
+ json_object_object_get_ex(dbscaleJ, "max", &tmpJ);
+ ctl->dbscale->max = (snd_ctl_elem_type_t) json_object_get_int(tmpJ);
+
+ json_object_object_get_ex(dbscaleJ, "step", &tmpJ);
+ ctl->dbscale->step = (snd_ctl_elem_type_t) json_object_get_int(tmpJ);
+
+ json_object_object_get_ex(dbscaleJ, "mute", &tmpJ);
+ ctl->dbscale->mute = (snd_ctl_elem_type_t) json_object_get_int(tmpJ);
}
}
-
+
return 0;
-
- OnErrorExit:
- return -1;
+
+OnErrorExit:
+ return -1;
}
// this is call when after all bindings are loaded
-PUBLIC int halServiceInit (const char *apiPrefix, alsaHalSndCardT *alsaHalSndCard) {
+
+PUBLIC int halServiceInit(const char *apiPrefix, alsaHalSndCardT *alsaHalSndCard) {
int err;
json_object *queryurl, *responseJ, *devidJ, *ctlsJ, *tmpJ;
- alsaHalMapT *halCtls= alsaHalSndCard->ctls;
-
+ alsaHalMapT *halCtls = alsaHalSndCard->ctls;
+
// if not volume normalisation CB provided use default one
- if (!alsaHalSndCard->volumeCB) alsaHalSndCard->volumeCB=volumeNormalise;
- halSndCard= alsaHalSndCard;
-
- err= afb_daemon_require_api("alsacore", 1);
+ if (!alsaHalSndCard->volumeCB) alsaHalSndCard->volumeCB = volumeNormalise;
+ halSndCard = alsaHalSndCard;
+
+ err = afb_daemon_require_api("alsacore", 1);
if (err) {
- AFB_ERROR ("AlsaCore missing cannot use AlsaHAL");
- goto OnErrorExit;
+ AFB_ERROR("AlsaCore missing cannot use AlsaHAL");
+ goto OnErrorExit;
}
// register HAL with Alsa Low Level Binder
queryurl = json_object_new_object();
json_object_object_add(queryurl, "prefix", json_object_new_string(apiPrefix));
json_object_object_add(queryurl, "sndname", json_object_new_string(alsaHalSndCard->name));
-
- err= afb_service_call_sync ("alsacore", "halregister", queryurl, &responseJ);
+
+ err = afb_service_call_sync("alsacore", "halregister", queryurl, &responseJ);
json_object_put(queryurl);
if (err) {
- AFB_NOTICE ("Fail to register HAL to ALSA lowlevel binding Response='%s'", json_object_get_string(responseJ));
+ AFB_NOTICE("Fail to register HAL to ALSA lowlevel binding Response='%s'", json_object_get_string(responseJ));
goto OnErrorExit;
}
-
+
// extract sound devidJ from HAL registration
if (!json_object_object_get_ex(responseJ, "response", &tmpJ) || !json_object_object_get_ex(tmpJ, "devid", &devidJ)) {
- AFB_ERROR ("Ooops: Internal error no devidJ return from HAL registration Response='%s'", json_object_get_string(responseJ));
+ AFB_ERROR("Ooops: Internal error no devidJ return from HAL registration Response='%s'", json_object_get_string(responseJ));
goto OnErrorExit;
}
-
+
// save devid for future use
- halSndCard->devid = strdup (json_object_get_string(devidJ));
-
+ halSndCard->devid = strdup(json_object_get_string(devidJ));
+
// for each Non Alsa Control callback create a custom control
- ctlsJ= json_object_new_array();
- for (int idx= 0; (halCtls[idx].ctl.name||halCtls[idx].ctl.numid); idx++) {
+ ctlsJ = json_object_new_array();
+ for (int idx = 0; (halCtls[idx].ctl.name || halCtls[idx].ctl.numid); idx++) {
json_object *ctlJ;
-
- // map HAL ctlTad with halCrlLabel to simplify set/get ctl operations using Labels
- halCtls[idx].label = halCtlsLabels[halCtls[idx].tag];
-
- if (halCtls[idx].cb.callback != NULL) {
- ctlJ = json_object_new_object();
- if (halCtls[idx].ctl.name) json_object_object_add(ctlJ, "name" , json_object_new_string(halCtls[idx].ctl.name));
- if (halCtls[idx].ctl.minval) json_object_object_add(ctlJ, "min" , json_object_new_int(halCtls[idx].ctl.minval));
- if (halCtls[idx].ctl.maxval) json_object_object_add(ctlJ, "max" , json_object_new_int(halCtls[idx].ctl.maxval));
- if (halCtls[idx].ctl.step) json_object_object_add(ctlJ, "step" , json_object_new_int(halCtls[idx].ctl.step));
- if (halCtls[idx].ctl.type) json_object_object_add(ctlJ, "type" , json_object_new_int(halCtls[idx].ctl.type));
- if (halCtls[idx].ctl.count) json_object_object_add(ctlJ, "count", json_object_new_int(halCtls[idx].ctl.count));
- if (halCtls[idx].ctl.value) json_object_object_add(ctlJ, "value", json_object_new_int(halCtls[idx].ctl.value));
-
- if (halCtls[idx].ctl.dbscale) {
- json_object *dbscaleJ=json_object_new_object();
- if (halCtls[idx].ctl.dbscale->max) json_object_object_add(dbscaleJ, "max" , json_object_new_int(halCtls[idx].ctl.dbscale->max));
- if (halCtls[idx].ctl.dbscale->min) json_object_object_add(dbscaleJ, "min" , json_object_new_int(halCtls[idx].ctl.dbscale->min));
- if (halCtls[idx].ctl.dbscale->step) json_object_object_add(dbscaleJ, "step", json_object_new_int(halCtls[idx].ctl.dbscale->step));
- if (halCtls[idx].ctl.dbscale->mute) json_object_object_add(dbscaleJ, "mute", json_object_new_int(halCtls[idx].ctl.dbscale->mute));
- json_object_object_add(ctlJ, "dbscale" , dbscaleJ);
- }
-
- if (halCtls[idx].ctl.enums) {
- json_object *enumsJ=json_object_new_array();
- for (int jdx=0; halCtls[idx].ctl.enums[jdx]; jdx++) {
- json_object_array_add(enumsJ, json_object_new_string(halCtls[idx].ctl.enums[jdx]));
- }
- json_object_object_add(ctlJ, "enums" , enumsJ);
+
+ // Try to find best equivalent label for tag
+ if (halCtls[idx].tag >StartHalCrlTag && halCtls[idx].tag < EndHalCrlTag && halCtls[idx].label != NULL) {
+ halCtls[idx].label = halCtlsLabels[halCtls[idx].tag];
+ } else {
+ if (halCtls[idx].ctl.name) halCtls[idx].label=halCtls[idx].ctl.name;
+ else if (halCtls[idx].info) halCtls[idx].label=halCtls[idx].info;
+ }
+
+ ctlJ = json_object_new_object();
+ if (halCtls[idx].ctl.numid) json_object_object_add(ctlJ, "ctl", json_object_new_int(halCtls[idx].ctl.numid));
+ if (halCtls[idx].ctl.name) json_object_object_add(ctlJ, "name", json_object_new_string(halCtls[idx].ctl.name));
+ if (halCtls[idx].ctl.minval) json_object_object_add(ctlJ, "min", json_object_new_int(halCtls[idx].ctl.minval));
+ if (halCtls[idx].ctl.maxval) json_object_object_add(ctlJ, "max", json_object_new_int(halCtls[idx].ctl.maxval));
+ if (halCtls[idx].ctl.step) json_object_object_add(ctlJ, "step", json_object_new_int(halCtls[idx].ctl.step));
+ if (halCtls[idx].ctl.type) json_object_object_add(ctlJ, "type", json_object_new_int(halCtls[idx].ctl.type));
+ if (halCtls[idx].ctl.count) json_object_object_add(ctlJ, "count", json_object_new_int(halCtls[idx].ctl.count));
+ if (halCtls[idx].ctl.value) json_object_object_add(ctlJ, "value", json_object_new_int(halCtls[idx].ctl.value));
+
+ if (halCtls[idx].ctl.dbscale) {
+ json_object *dbscaleJ = json_object_new_object();
+ if (halCtls[idx].ctl.dbscale->max) json_object_object_add(dbscaleJ, "max", json_object_new_int(halCtls[idx].ctl.dbscale->max));
+ if (halCtls[idx].ctl.dbscale->min) json_object_object_add(dbscaleJ, "min", json_object_new_int(halCtls[idx].ctl.dbscale->min));
+ if (halCtls[idx].ctl.dbscale->step) json_object_object_add(dbscaleJ, "step", json_object_new_int(halCtls[idx].ctl.dbscale->step));
+ if (halCtls[idx].ctl.dbscale->mute) json_object_object_add(dbscaleJ, "mute", json_object_new_int(halCtls[idx].ctl.dbscale->mute));
+ json_object_object_add(ctlJ, "dbscale", dbscaleJ);
+ }
+
+ if (halCtls[idx].ctl.enums) {
+ json_object *enumsJ = json_object_new_array();
+ for (int jdx = 0; halCtls[idx].ctl.enums[jdx]; jdx++) {
+ json_object_array_add(enumsJ, json_object_new_string(halCtls[idx].ctl.enums[jdx]));
}
- json_object_array_add(ctlsJ, ctlJ);
- } else {
- ctlJ = json_object_new_object();
- if (halCtls[idx].ctl.numid) json_object_object_add(ctlJ, "ctl" , json_object_new_int(halCtls[idx].ctl.numid));
- if (halCtls[idx].ctl.name) json_object_object_add(ctlJ, "name" , json_object_new_string(halCtls[idx].ctl.name));
- json_object_array_add(ctlsJ, ctlJ);
- }
+ json_object_object_add(ctlJ, "enums", enumsJ);
+ }
+ json_object_array_add(ctlsJ, ctlJ);
}
-
+
// Build new queryJ to add HAL custom control if any
- if (json_object_array_length (ctlsJ) > 0) {
+ if (json_object_array_length(ctlsJ) > 0) {
queryurl = json_object_new_object();
json_object_get(devidJ); // make sure devidJ does not get free by 1st call.
- json_object_object_add(queryurl, "devid",devidJ);
- json_object_object_add(queryurl, "ctl",ctlsJ);
- json_object_object_add(queryurl, "mode",json_object_new_int(QUERY_COMPACT));
- err= afb_service_call_sync ("alsacore", "addcustomctl", queryurl, &responseJ);
+ json_object_object_add(queryurl, "devid", devidJ);
+ json_object_object_add(queryurl, "ctl", ctlsJ);
+ json_object_object_add(queryurl, "mode", json_object_new_int(QUERY_COMPACT));
+ err = afb_service_call_sync("alsacore", "addcustomctl", queryurl, &responseJ);
if (err) {
- AFB_ERROR ("Fail creating HAL Custom ALSA ctls Response='%s'", json_object_get_string(responseJ));
+ AFB_ERROR("Fail creating HAL Custom ALSA ctls Response='%s'", json_object_get_string(responseJ));
goto OnErrorExit;
- }
+ }
}
// Make sure response is valid
- json_object_object_get_ex (responseJ, "response" , &ctlsJ);
+ json_object_object_get_ex(responseJ, "response", &ctlsJ);
if (json_object_get_type(ctlsJ) != json_type_array) {
- AFB_ERROR ("Response Invalid JSON array ctls Response='%s'", json_object_get_string(responseJ));
- goto OnErrorExit;
+ AFB_ERROR("Response Invalid JSON array ctls Response='%s'", json_object_get_string(responseJ));
+ goto OnErrorExit;
}
-
+
// update HAL data from JSON response
- for (int idx= 0; idx < json_object_array_length (ctlsJ); idx++) {
- json_object *ctlJ = json_object_array_get_idx (ctlsJ, idx);
- err= UpdateOneSndCtl(&halCtls[idx].ctl, ctlJ) ;
+ for (int idx = 0; idx < json_object_array_length(ctlsJ); idx++) {
+ json_object *ctlJ = json_object_array_get_idx(ctlsJ, idx);
+ err = UpdateOneSndCtl(&halCtls[idx].ctl, ctlJ);
if (err) {
- AFB_ERROR ("Fail found MAP Alsa Low level=%s", json_object_get_string(ctlJ));
- goto OnErrorExit;
+ AFB_ERROR("Fail found MAP Alsa Low level=%s", json_object_get_string(ctlJ));
+ goto OnErrorExit;
}
}
-
+
// finally register for alsa lowlevel event
queryurl = json_object_new_object();
- json_object_object_add(queryurl, "devid",devidJ);
- err= afb_service_call_sync ("alsacore", "subscribe", queryurl, &responseJ);
+ json_object_object_add(queryurl, "devid", devidJ);
+ err = afb_service_call_sync("alsacore", "subscribe", queryurl, &responseJ);
if (err) {
- AFB_ERROR ("Fail subscribing to ALSA lowlevel events");
+ AFB_ERROR("Fail subscribing to ALSA lowlevel events");
goto OnErrorExit;
}
-
- return (0);
-
- OnErrorExit:
+
+ return (0);
+
+OnErrorExit:
return (1);
};
// This receive all event this binding subscribe to
+
PUBLIC void halServiceEvent(const char *evtname, json_object *eventJ) {
int numid;
- alsaHalMapT *halCtls= halSndCard->ctls;
+ alsaHalMapT *halCtls = halSndCard->ctls;
json_object *numidJ, *valuesJ;
-
+
AFB_DEBUG("halServiceEvent evtname=%s [msg=%s]", evtname, json_object_get_string(eventJ));
-
- json_object_object_get_ex (eventJ, "id" , &numidJ);
- numid = json_object_get_int (numidJ);
+
+ json_object_object_get_ex(eventJ, "id", &numidJ);
+ numid = json_object_get_int(numidJ);
if (!numid) {
AFB_ERROR("halServiceEvent noid: evtname=%s [msg=%s]", evtname, json_object_get_string(eventJ));
return;
}
- json_object_object_get_ex (eventJ, "val" , &valuesJ);
-
+ json_object_object_get_ex(eventJ, "val", &valuesJ);
+
// search it corresponding numid in halCtls attach a callback
if (numid) {
- for (int idx= 0; halCtls[idx].ctl.numid; idx++) {
+ for (int idx = 0; halCtls[idx].ctl.numid; idx++) {
if (halCtls[idx].ctl.numid == numid && halCtls[idx].cb.callback != NULL) {
- halCtls[idx].cb.callback (halCtls[idx].tag, &halCtls[idx].ctl, halCtls[idx].cb.handle, valuesJ);
+ halCtls[idx].cb.callback(halCtls[idx].tag, &halCtls[idx].ctl, halCtls[idx].cb.handle, valuesJ);
}
}
- }
+ }
}
// Every HAL export the same API & Interface Mapping from SndCard to AudioLogic is done through alsaHalSndCardT
PUBLIC afb_verb_v2 halServiceApi[] = {
/* VERB'S NAME FUNCTION TO CALL SHORT DESCRIPTION */
- { .verb = "ping", .callback = pingtest , .info="ping test for API"},
- { .verb = "ctl-list", .callback = halListCtls , .info="List AGL normalised Sound Controls"},
- { .verb = "ctl-get", .callback = halGetCtls , .info="Get one/many sound controls"},
- { .verb = "ctl-set", .callback = halSetCtls , .info="Set one/many sound controls"},
- { .verb = "evt-sub", .callback = halSubscribe, .info="Subscribe to HAL events"},
+ { .verb = "ping", .callback = pingtest, .info = "ping test for API"},
+ { .verb = "ctl-list", .callback = halListCtls, .info = "List AGL normalised Sound Controls"},
+ { .verb = "ctl-get", .callback = halGetCtls, .info = "Get one/many sound controls"},
+ { .verb = "ctl-set", .callback = halSetCtls, .info = "Set one/many sound controls"},
+ { .verb = "evt-sub", .callback = halSubscribe, .info = "Subscribe to HAL events"},
{ .verb = NULL} /* marker for end of the array */
};
diff --git a/HAL-afb/HAL-interface/hal-interface.h b/HAL-afb/HAL-interface/hal-interface.h
index 23944ad..a6310e7 100644
--- a/HAL-afb/HAL-interface/hal-interface.h
+++ b/HAL-afb/HAL-interface/hal-interface.h
@@ -24,22 +24,22 @@
#include "audio-interface.h"
#include <systemd/sd-event.h>
-
typedef enum {
- ACTION_SET,
- ACTION_GET
+ ACTION_SET,
+ ACTION_GET
} ActionSetGetT;
// VolRamp Handle Store current status for a given VolRam CB set
+
typedef struct {
- halRampEnumT mode;
- halCtlsEnumT slave;
- int delay; // delay between volset in us
- int stepDown; // linear %
- int stepUp; // linear %
- int current; // current volume for slave ctl
- int target; // target volume
- sd_event_source *evtsrc; // event loop timer source
+ halRampEnumT mode;
+ halCtlsTagT slave;
+ int delay; // delay between volset in us
+ int stepDown; // linear %
+ int stepUp; // linear %
+ int current; // current volume for slave ctl
+ int target; // target volume
+ sd_event_source *evtsrc; // event loop timer source
} halVolRampT;
typedef struct {
@@ -50,56 +50,56 @@ typedef struct {
} alsaHalDBscaleT;
typedef struct {
- char* name;
- int numid;
- snd_ctl_elem_type_t type;
- int count;
- int minval;
- int maxval;
- int value;
- int step;
- char **enums;
- alsaHalDBscaleT *dbscale;
+ char* name;
+ int numid;
+ snd_ctl_elem_type_t type;
+ int count;
+ int minval;
+ int maxval;
+ int value;
+ int step;
+ const char **enums;
+ alsaHalDBscaleT *dbscale;
} alsaHalCtlMapT;
+
// avoid compiler warning [Jose does not like typedef :) ]
typedef struct afb_service alsaHalServiceT;
typedef struct {
- void (*callback)(halCtlsEnumT tag, alsaHalCtlMapT *control, void* handle, json_object *valuesJ);
- void* handle;
+ void (*callback)(halCtlsTagT tag, alsaHalCtlMapT *control, void* handle, json_object *valuesJ);
+ void* handle;
} alsaHalCbMapT;
typedef struct {
- halCtlsEnumT tag;
+ halCtlsTagT tag;
const char *label;
alsaHalCtlMapT ctl;
alsaHalCbMapT cb;
char* info;
} alsaHalMapT;
-typedef struct {
- const char *name;
- const char *info;
- alsaHalMapT *ctls;
- const char *devid;
- json_object* (*volumeCB)(ActionSetGetT action, const alsaHalCtlMapT *halCtls, json_object *valuesJ);
+typedef struct {
+ const char *name;
+ const char *info;
+ alsaHalMapT *ctls;
+ const char *devid;
+ json_object* (*volumeCB)(ActionSetGetT action, const alsaHalCtlMapT *halCtls, json_object *valuesJ);
} alsaHalSndCardT;
// hal-interface.c
extern afb_verb_v2 halServiceApi[];
-extern char *halVolRampModes[];
PUBLIC void halServiceEvent(const char *evtname, json_object *object);
-PUBLIC int halServiceInit (const char *apiPrefix, alsaHalSndCardT *alsaHalSndCard);
-PUBLIC json_object *halGetCtlByTag (halRampEnumT tag);
-PUBLIC int halSetCtlByTag (halRampEnumT tag, int value);
+PUBLIC int halServiceInit(const char *apiPrefix, alsaHalSndCardT *alsaHalSndCard);
+PUBLIC json_object *halGetCtlByTag(halRampEnumT tag);
+PUBLIC int halSetCtlByTag(halRampEnumT tag, int value);
// hal-volramp.c
-PUBLIC void volumeRamp (halCtlsEnumT halTag,alsaHalCtlMapT *control, void* handle, json_object *valJ);
+PUBLIC void volumeRamp(halCtlsTagT halTag, alsaHalCtlMapT *control, void* handle, json_object *valJ);
// hal-volume.c
-PUBLIC json_object *volumeNormalise(ActionSetGetT action, const alsaHalCtlMapT *halCtls, json_object *valuesJ);
+PUBLIC json_object *volumeNormalise(ActionSetGetT action, const alsaHalCtlMapT *halCtls, json_object *valuesJ);
#endif /* SHAREHALLIB_H */
diff --git a/HAL-afb/HAL-interface/hal-volramp.c b/HAL-afb/HAL-interface/hal-volramp.c
index 6343a06..eb39aae 100644
--- a/HAL-afb/HAL-interface/hal-volramp.c
+++ b/HAL-afb/HAL-interface/hal-volramp.c
@@ -19,26 +19,26 @@
#define _GNU_SOURCE // needed for vasprintf
#include "hal-interface.h"
-STATIC int RampTimerCB (sd_event_source* source,uint64_t timer, void* handle) {
- halVolRampT *volRamp= (halVolRampT*)handle;
- int err;
- uint64_t usec;
+STATIC int RampTimerCB(sd_event_source* source, uint64_t timer, void* handle) {
+ halVolRampT *volRamp = (halVolRampT*) handle;
+ int err;
+ uint64_t usec;
// RampDown
if (volRamp->current > volRamp->target) {
- volRamp->current = volRamp->current - volRamp->stepDown;
- if (volRamp->current < volRamp->target) volRamp->current = volRamp->target;
+ volRamp->current = volRamp->current - volRamp->stepDown;
+ if (volRamp->current < volRamp->target) volRamp->current = volRamp->target;
}
-
+
// RampUp
if (volRamp->current < volRamp->target) {
- volRamp->current = volRamp->current + volRamp->stepUp;
- if (volRamp->current > volRamp->target) volRamp->current = volRamp->target;
+ volRamp->current = volRamp->current + volRamp->stepUp;
+ if (volRamp->current > volRamp->target) volRamp->current = volRamp->target;
}
-
+
// request current Volume Level
err = halSetCtlByTag(volRamp->slave, volRamp->current);
- if (err) goto OnErrorExit;
+ if (err) goto OnErrorExit;
// we reach target stop volram event
if (volRamp->current == volRamp->target) sd_event_source_unref(source);
@@ -46,121 +46,140 @@ STATIC int RampTimerCB (sd_event_source* source,uint64_t timer, void* handle) {
// otherwise validate timer for a new run
sd_event_now(afb_daemon_get_event_loop(), CLOCK_MONOTONIC, &usec);
sd_event_source_set_enabled(source, SD_EVENT_ONESHOT);
- err=sd_event_source_set_time(source, usec+volRamp->delay);
+ err = sd_event_source_set_time(source, usec + volRamp->delay);
}
return 0;
-
- OnErrorExit:
- AFB_WARNING ("RampTimerCB Fail to set HAL ctl tag=%d vol=%d", Master_Playback_Volume, volRamp->current);
+
+OnErrorExit:
+ AFB_WARNING("RampTimerCB Fail to set HAL ctl tag=%d vol=%d", Master_Playback_Volume, volRamp->current);
sd_event_source_unref(source); // abandon VolRamp
return -1;
}
-/* UCS2 Interface Timer Callback */
STATIC void SetRampTimer(void *handle) {
- halVolRampT *volRamp= (halVolRampT*)handle;
-
- uint64_t usec;
- /* set a timer with 250ms accuracy */
- sd_event_now(afb_daemon_get_event_loop(), CLOCK_MONOTONIC, &usec);
- sd_event_add_time(afb_daemon_get_event_loop(), &volRamp->evtsrc, CLOCK_MONOTONIC, usec, 250, RampTimerCB, volRamp);
+ halVolRampT *volRamp = (halVolRampT*) handle;
+ uint64_t usec;
+
+ // set a timer with ~250us accuracy
+ sd_event_now(afb_daemon_get_event_loop(), CLOCK_MONOTONIC, &usec);
+ sd_event_add_time(afb_daemon_get_event_loop(), &volRamp->evtsrc, CLOCK_MONOTONIC, usec, 250, RampTimerCB, volRamp);
}
-STATIC int volumeDoRamp (halVolRampT *volRamp, int numid, json_object *volumeJ) {
+STATIC int volumeDoRamp(halVolRampT *volRamp, int numid, json_object *volumeJ) {
json_object *responseJ;
-
+
// request current Volume Level
responseJ = halGetCtlByTag(volRamp->slave);
if (!responseJ) {
- AFB_WARNING ("volumeDoRamp Fail to get HAL ctl tag=%d", Master_Playback_Volume);
+ AFB_WARNING("volumeDoRamp Fail to get HAL ctl tag=%d", Master_Playback_Volume);
goto OnErrorExit;
- }
-
+ }
+
// use 1st volume value as target for ramping
switch (json_object_get_type(volumeJ)) {
case json_type_array:
- volRamp->target=json_object_get_int(json_object_array_get_idx(volumeJ,0));
+ volRamp->target = json_object_get_int(json_object_array_get_idx(volumeJ, 0));
break;
-
+
case json_type_int:
- volRamp->target=json_object_get_int(volumeJ);
+ volRamp->target = json_object_get_int(volumeJ);
break;
-
+
default:
- AFB_WARNING ("volumeDoRamp Invalid volumeJ=%s", json_object_get_string(volumeJ));
+ AFB_WARNING("volumeDoRamp Invalid volumeJ=%s", json_object_get_string(volumeJ));
goto OnErrorExit;
}
-
+
// use 1st volume value as current for ramping
switch (json_object_get_type(responseJ)) {
case json_type_array:
- volRamp->current=json_object_get_int(json_object_array_get_idx(responseJ,0));
+ volRamp->current = json_object_get_int(json_object_array_get_idx(responseJ, 0));
break;
-
+
case json_type_int:
- volRamp->current=json_object_get_int(responseJ);
+ volRamp->current = json_object_get_int(responseJ);
break;
-
+
default:
- AFB_WARNING ("volumeDoRamp Invalid reponseJ=%s", json_object_get_string(responseJ));
+ AFB_WARNING("volumeDoRamp Invalid reponseJ=%s", json_object_get_string(responseJ));
goto OnErrorExit;
}
-
- SetRampTimer (volRamp);
-
+
+ SetRampTimer(volRamp);
+
return 0;
- OnErrorExit:
+OnErrorExit:
return -1;
}
-
-PUBLIC void volumeRamp (halCtlsEnumT halTag, alsaHalCtlMapT *ctl, void* handle, json_object *valJ) {
+PUBLIC void volumeRamp(halCtlsTagT halTag, alsaHalCtlMapT *ctl, void* handle, json_object *valJ) {
halVolRampT *volRamp = (halVolRampT*) handle;
json_object *tmpJ;
- if (json_object_get_type(valJ) != json_type_array || volRamp==NULL) goto OnErrorExit;
-
+ if (json_object_get_type(valJ) != json_type_array || volRamp == NULL) goto OnErrorExit;
+
switch (halTag) {
- case Vol_Ramp:
- tmpJ = json_object_array_get_idx(valJ, 0);
- volumeDoRamp (volRamp, ctl->numid, tmpJ);
+
+ // Only config use wellknown tag. Default is DoVolRamp
+ default:
+ tmpJ = json_object_array_get_idx(valJ, 0);
+ volumeDoRamp(volRamp, ctl->numid, tmpJ);
break;
-
+
case Vol_Ramp_Set_Mode:
- tmpJ = json_object_array_get_idx(valJ, 0);
- volRamp->mode = json_object_get_int (tmpJ);
+ tmpJ = json_object_array_get_idx(valJ, 0);
+ volRamp->mode = json_object_get_int(tmpJ);
+ switch (volRamp->mode) {
+
+ case RAMP_VOL_SMOOTH:
+ volRamp->delay = 100 * 1000;
+ volRamp->stepDown = 1;
+ volRamp->stepUp = 1;
+ break;
+
+ case RAMP_VOL_NORMAL:
+ volRamp->delay = 100 * 1000;
+ volRamp->stepDown = 3;
+ volRamp->stepUp = 2;
+ break;
+
+ case RAMP_VOL_EMERGENCY:
+ volRamp->delay = 50 * 1000;
+ volRamp->stepDown = 6;
+ volRamp->stepUp = 2;
+ break;
+
+ default:
+ goto OnErrorExit;
+ }
break;
-
+
case Vol_Ramp_Set_Slave:
- tmpJ = json_object_array_get_idx(valJ, 0);
- volRamp->slave = json_object_get_int (tmpJ);
+ tmpJ = json_object_array_get_idx(valJ, 0);
+ volRamp->slave = json_object_get_int(tmpJ);
break;
-
+
case Vol_Ramp_Set_Delay:
- tmpJ = json_object_array_get_idx(valJ, 0);
- volRamp->delay = 1000*json_object_get_int (tmpJ);
+ tmpJ = json_object_array_get_idx(valJ, 0);
+ volRamp->delay = 1000 * json_object_get_int(tmpJ);
break;
case Vol_Ramp_Set_Down:
- tmpJ = json_object_array_get_idx(valJ, 0);
- volRamp->stepDown = json_object_get_int (tmpJ);
+ tmpJ = json_object_array_get_idx(valJ, 0);
+ volRamp->stepDown = json_object_get_int(tmpJ);
break;
case Vol_Ramp_Set_Up:
- tmpJ = json_object_array_get_idx(valJ, 0);
- volRamp->stepUp = json_object_get_int (tmpJ);
+ tmpJ = json_object_array_get_idx(valJ, 0);
+ volRamp->stepUp = json_object_get_int(tmpJ);
break;
-
- default:
- goto OnErrorExit;
}
-
+
+ return;
+
+OnErrorExit:
+ AFB_WARNING("volumeRamp: Invalid Ctrl Event halCtlsTagT=%d numid=%d name=%s value=%s", halTag, ctl->numid, ctl->name, json_object_get_string(valJ));
return;
-
- OnErrorExit:
- AFB_WARNING ("Invalid Ctrl Event halCtlsEnumT=%d numid=%d name=%s value=%s", halTag, ctl->numid, ctl->name, json_object_get_string(valJ));
- return;
}
- \ No newline at end of file
diff --git a/HAL-afb/HAL-interface/hal-volume.c b/HAL-afb/HAL-interface/hal-volume.c
index 593b74c..ad2b9a1 100644
--- a/HAL-afb/HAL-interface/hal-volume.c
+++ b/HAL-afb/HAL-interface/hal-volume.c
@@ -25,126 +25,126 @@
#include <math.h>
#include "hal-interface.h"
-
-typedef enum {
- NORMALIZE_NONE=0,
- NORMALIZE_DB_LINEAR,
- NORMALIZE_DB_MATH,
- NORMALIZE_LINEAR,
+typedef enum {
+ NORMALIZE_NONE = 0,
+ NORMALIZE_DB_LINEAR,
+ NORMALIZE_DB_MATH,
+ NORMALIZE_LINEAR,
} enumRandeModeDB_T;
// Return Value express from 0-100%
-STATIC int dbNormalizeVal (enumRandeModeDB_T normaliseMode, const alsaHalDBscaleT *dbscale, int value) {
+
+STATIC int dbNormalizeVal(enumRandeModeDB_T normaliseMode, const alsaHalDBscaleT *dbscale, int value) {
double normalized, min_norm;
// To get real DB from TLV DB values should be divided by 100
switch (normaliseMode) {
case NORMALIZE_DB_LINEAR:
- normalized = ((double)(value-dbscale->min)/(double)(dbscale->max-dbscale->min));
+ normalized = ((double) (value - dbscale->min) / (double) (dbscale->max - dbscale->min));
break;
-
- case NORMALIZE_DB_MATH:
- normalized = exp10((double)(value - dbscale->max) / 6000.0);
+
+ case NORMALIZE_DB_MATH:
+ normalized = exp10((double) (value - dbscale->max) / 6000.0);
if (dbscale->min != SND_CTL_TLV_DB_GAIN_MUTE) {
- min_norm = exp10((double)(dbscale->min - dbscale->max) / 20);
- normalized = (normalized - min_norm) / (1 - min_norm);
+ min_norm = exp10((double) (dbscale->min - dbscale->max) / 20);
+ normalized = (normalized - min_norm) / (1 - min_norm);
}
-
+
break;
-
+
default:
- normalized=0;
+ normalized = 0;
}
-
- return (int)round(normalized*100);
+
+ return (int) round(normalized * 100);
}
// HAL normalise volume values to 0-100%
-PUBLIC json_object *volumeNormalise(ActionSetGetT action, const alsaHalCtlMapT *halCtls, json_object *valuesJ) {
+
+PUBLIC json_object *volumeNormalise(ActionSetGetT action, const alsaHalCtlMapT *halCtls, json_object *valuesJ) {
enumRandeModeDB_T useNormalizeDB;
int length;
// If Integer look for DBscale
if (halCtls->type == SND_CTL_ELEM_TYPE_INTEGER) {
-
+
// If not valid db_scale let's use raw_scale
if (!halCtls->dbscale || (halCtls->dbscale->min >= halCtls->dbscale->max)) {
-
- // dbscale is invalid let's try raw range
- if (halCtls->minval >= halCtls->maxval) goto ExitOnError;
-
- // Use Raw Scale Model
- useNormalizeDB= NORMALIZE_LINEAR;
-
+
+ // dbscale is invalid let's try raw range
+ if (halCtls->minval >= halCtls->maxval) goto ExitOnError;
+
+ // Use Raw Scale Model
+ useNormalizeDB = NORMALIZE_LINEAR;
+
} else { // db_scale looks OK let's use it
- if ((halCtls->dbscale->max - halCtls->dbscale->min) <= MAX_LINEAR_DB_SCALE * 100) useNormalizeDB= NORMALIZE_DB_LINEAR;
+ if ((halCtls->dbscale->max - halCtls->dbscale->min) <= MAX_LINEAR_DB_SCALE * 100) useNormalizeDB = NORMALIZE_DB_LINEAR;
else useNormalizeDB = NORMALIZE_LINEAR; // Fulup not sure how to handle this useNormalizeDB=NORMALIZE_DB_MATH;
}
- } else useNormalizeDB= NORMALIZE_NONE;
-
-
+ } else useNormalizeDB = NORMALIZE_NONE;
+
+
// loop on values to normalise
- enum json_type jtype=json_object_get_type(valuesJ);
- if (jtype == json_type_array) length = json_object_array_length(valuesJ);
+ enum json_type jtype = json_object_get_type(valuesJ);
+ if (jtype == json_type_array) length = json_object_array_length(valuesJ);
else length = 1;
-
- json_object *normalisedJ= json_object_new_array();
- for (int idx=0; idx < length; idx++) {
+
+ json_object *normalisedJ = json_object_new_array();
+ for (int idx = 0; idx < length; idx++) {
int value;
-
+
if (jtype == json_type_array) {
- json_object *valueJ = json_object_array_get_idx (valuesJ, idx);
+ json_object *valueJ = json_object_array_get_idx(valuesJ, idx);
value = json_object_get_int(valueJ);
} else {
value = json_object_get_int(valuesJ);
}
-
+
// If Integer scale to 0/100
if (halCtls->type == SND_CTL_ELEM_TYPE_INTEGER) {
-
+
switch (action) {
-
+
case ACTION_GET:
- switch (useNormalizeDB) {
+ switch (useNormalizeDB) {
case NORMALIZE_LINEAR:
- value = 100* (value - halCtls->minval) / (halCtls->maxval - halCtls->minval);
+ value = 100 * (value - halCtls->minval) / (halCtls->maxval - halCtls->minval);
break;
case NORMALIZE_DB_MATH: //ToBeDone
- value = dbNormalizeVal (useNormalizeDB, halCtls->dbscale, value);
+ value = dbNormalizeVal(useNormalizeDB, halCtls->dbscale, value);
break;
- case NORMALIZE_NONE:
+ case NORMALIZE_NONE:
default:
value = value;
}
break;
-
- case ACTION_SET:
- switch (useNormalizeDB) {
+
+ case ACTION_SET:
+ switch (useNormalizeDB) {
case NORMALIZE_LINEAR:
- value = (value * (halCtls->maxval - halCtls->minval))/100;
+ value = (value * (halCtls->maxval - halCtls->minval)) / 100;
break;
case NORMALIZE_DB_MATH: //ToBeDone
- value = dbNormalizeVal (useNormalizeDB, halCtls->dbscale, value);
+ value = dbNormalizeVal(useNormalizeDB, halCtls->dbscale, value);
break;
- case NORMALIZE_NONE:
+ case NORMALIZE_NONE:
default:
value = value;
}
break;
-
- default:
- AFB_NOTICE ("volumeNormalise: invalid action value=%d", (int)action);
- goto ExitOnError;
+
+ default:
+ AFB_NOTICE("volumeNormalise: invalid action value=%d", (int) action);
+ goto ExitOnError;
}
- }
-
- json_object_array_add(normalisedJ, json_object_new_int(value));
+ }
+
+ json_object_array_add(normalisedJ, json_object_new_int(value));
}
-
+
return (normalisedJ);
-
- ExitOnError:
- return NULL;
+
+ExitOnError:
+ return NULL;
}
- \ No newline at end of file
diff --git a/HAL-afb/HAL-plugin/CMakeLists.txt b/HAL-afb/HAL-plugin/CMakeLists.txt
deleted file mode 100644
index 93642b2..0000000
--- a/HAL-afb/HAL-plugin/CMakeLists.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-###########################################################################
-# Copyright 2015, 2016, 2017 IoT.bzh
-#
-# author: Fulup Ar Foll <fulup@iot.bzh>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-###########################################################################
-
-# Activate ALSA dynamic build build mode get resolve "snd_dlsym_start"
-add_compile_options(-DPIC)
-
-# Add target to project dependency list
-PROJECT_TARGET_ADD(ctl_afbhal)
-
- # Define targets
- ADD_LIBRARY(${TARGET_NAME} MODULE HalPlugCtl.c)
-
- # Alsa Plugin properties
- SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
- PREFIX "libasound_module_"
- OUTPUT_NAME ${TARGET_NAME}
- )
-
- # Library dependencies (include updates automatically)
- TARGET_LINK_LIBRARIES(${TARGET_NAME}
- ${link_libraries}
- )
- install(TARGETS ${TARGET_NAME} LIBRARY DESTINATION lib/alsa-lib)
-
-PROJECT_TARGET_ADD(cb_sample)
-
- # Define targets
- ADD_LIBRARY(${TARGET_NAME} MODULE HalPlugCb.c)
-
- # Alsa Plugin properties
- SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
- PREFIX "afbhal_"
- OUTPUT_NAME ${TARGET_NAME}
- )
-
- # Library dependencies (include updates automatically)
- TARGET_LINK_LIBRARIES(${TARGET_NAME}
- ${link_libraries}
- )
- install(TARGETS ${TARGET_NAME} LIBRARY DESTINATION lib)
diff --git a/HAL-afb/HAL-plugin/HalPlug.h b/HAL-afb/HAL-plugin/HalPlug.h
deleted file mode 100644
index 5e3da6f..0000000
--- a/HAL-afb/HAL-plugin/HalPlug.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2016 "IoT.bzh"
- * Author Fulup Ar Foll <fulup@iot.bzh>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * AfbCallBack (snd_ctl_hal_t *handle, int numid, void **response);
- * AfbHalInit is mandatory and called with numid=0
- *
- * Syntaxe in .asoundrc file
- * CrlLabel { cb MyFunctionName name "My_Second_Control" }
- */
-
-
-#include <alsa/asoundlib.h>
-#include <alsa/control_external.h>
-#include <linux/soundcard.h>
-
-#ifndef SOUND_HAL_MAX_CTLS
-#define SOUND_HAL_MAX_CTLS 255
-#endif
-
-
-typedef enum {
- CTLCB_INIT ,
- CTLCB_CLOSE ,
- CTLCB_ELEM_COUNT ,
- CTLCB_ELEM_LIST ,
- CTLCB_FIND_ELEM ,
- CTLCB_FREE_KEY ,
- CTLCB_GET_ATTRIBUTE ,
- CTLCB_GET_INTEGER_INFO ,
- CTLCB_GET_INTEGER64_INFO ,
- CTLCB_GET_ENUMERATED_INFO ,
- CTLCB_GET_ENUMERATED_NAME ,
- CTLCB_READ_INTEGER ,
- CTLCB_READ_INTEGER64 ,
- CTLCB_READ_ENUMERATED ,
- CTLCB_READ_BYTES ,
- CTLCB_READ_IEC958 ,
- CTLCB_WRITE_INTEGER ,
- CTLCB_WRITE_INTEGER64 ,
- CTLCB_WRITE_ENUMERATED ,
- CTLCB_WRITE_BYTES ,
- CTLCB_WRITE_IEC958 ,
- CTLCB_SUBSCRIBE_EVENTS ,
- CTLCB_READ_EVENT ,
- CTLCB_POLL_DESCRIPTORS_COUNT ,
- CTLCB_POLL_DESCRIPTORS
-} snd_ctl_action_t;
-
-typedef struct {
- int ctlNumid;
- const char *ctlName;
-} snd_ctl_conf_t;
-
-typedef struct {
- int type;
- int acc;
- unsigned count;
-} snd_ctl_get_attrib_t;
-
-typedef struct {
- int imin;
- int imax;
- int istep;
-} snd_ctl_get_int_info_t;
-
-typedef int(*snd_ctl_cb_t)(void *handle, snd_ctl_action_t action, snd_ctl_ext_key_t key, void *response);
-
-typedef struct snd_ctl_hal {
- snd_ctl_ext_t ext;
- char *devid;
- snd_ctl_t *ctlDev;
- unsigned int ctlsCount;
- void *dlHandle;
- snd_ctl_conf_t ctls[SOUND_HAL_MAX_CTLS];
- snd_ctl_elem_info_t *infos[SOUND_HAL_MAX_CTLS];
- snd_ctl_cb_t cbs[SOUND_HAL_MAX_CTLS];
-} snd_ctl_hal_t;
-
-
diff --git a/HAL-afb/HAL-plugin/HalPlugCb.c b/HAL-afb/HAL-plugin/HalPlugCb.c
deleted file mode 100644
index 362858d..0000000
--- a/HAL-afb/HAL-plugin/HalPlugCb.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2016 "IoT.bzh"
- * Author Fulup Ar Foll <fulup@iot.bzh>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * AfbCallBack (snd_ctl_hal_t *handle, int numid, void **response);
- * AfbHalInit is mandatory and called with numid=0
- *
- * Syntax in .asoundrc file
- * CrlLabel { cb MyFunctionName name "My_Second_Control" }
- *
- * Testing:
- * amixer -Dagl_hal controls
- * amixer -Dagl_hal cget name=My_Sample_Callback
- */
-
-
-#include "HalPlug.h"
-#include <stdio.h>
-
-int AfbHalInitCB (void *handle, snd_ctl_action_t action, int numid, void*response) {
- snd_ctl_hal_t *plughandle = (snd_ctl_hal_t*)handle;
-
- fprintf (stdout, "\n - CB AfbHalInit devid=%s\n", plughandle->devid);
- return 0;
-}
-
-int AfbHalSampleCB (void *handle, snd_ctl_action_t action, snd_ctl_ext_key_t key, void*response) {
-
- switch (action) {
- case CTLCB_GET_ATTRIBUTE: {
- fprintf (stdout, " - AfbHalSampleCB CTLCB_GET_ATTRIBUTE numid=%d\n", (int)key+1);
- snd_ctl_get_attrib_t *item = (snd_ctl_get_attrib_t*)response;
- item->type = 1;
- item->count= 2;
- item->acc = SND_CTL_EXT_ACCESS_READWRITE;
- break;
- }
-
- case CTLCB_GET_INTEGER_INFO: {
- fprintf (stdout, " - AfbHalSampleCB CTLCB_GET_INTEGER_INFO numid=%d\n", (int)key+1);
- snd_ctl_get_int_info_t *item = (snd_ctl_get_attrib_t*)response;
- item->istep= 10;
- item->imin = 20;
- item->imax = 200;
- break;
- }
-
- default:
- fprintf (stdout, "CB AfbHalSampleCB unsupported action=%d numid=%d\n", action, (int)key+1);
- }
- return 0;
-}
diff --git a/HAL-afb/HAL-plugin/HalPlugCtl.c b/HAL-afb/HAL-plugin/HalPlugCtl.c
deleted file mode 100644
index 4f76595..0000000
--- a/HAL-afb/HAL-plugin/HalPlugCtl.c
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * Copyright (C) 2016 "IoT.bzh"
- * Author Fulup Ar Foll <fulup@iot.bzh>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Testing:
- * 1) Copy generated plugin [libasound_module_pcm_afbhal.so] in alsa-lib/ dir visible from LD_LIBRARY_PATH (eg: /usr/lib64/alsa-lib)
- * 2) Create a ~/.asounrc file base on following template
- * ctl.agl_hal {
- * type afbhal
- * devid "hw:4"
- * cblib "afbhal_cb_sample.so"
- * ctls {
- * # ctlLabel {numid integer name "Alsa Ctl Name"}
- * MasterSwitch { numid 4 name "My_First_Control" }
- * MasterVol { numid 5 name "My_Second_Control" }
- * CB_sample { ctlcb @AfbHalSampleCB name "My_Sample_Callback"}
- * }
- * pcm.agl_hal {
- * type copy # Copy PCM
- * slave "hw:4" # Slave name
- * }
- *
- * }
- * 3) Test with
- * - amixer -Dagl_hal controls # should list all your controls
- * - amixer -Dagl_hal cget numid=1
- * - amixer -Dagl_hal cset numid=1 '10,20'
- */
-
-
-#include <stdio.h>
-#include <sys/ioctl.h>
-#include "HalPlug.h"
-#include <dlfcn.h>
-
-
-static snd_ctl_ext_key_t AfbHalElemFind(snd_ctl_ext_t *ext, const snd_ctl_elem_id_t *id) {
- snd_ctl_hal_t *plughandle = (snd_ctl_hal_t*) ext->private_data;
- snd_ctl_ext_key_t key=NULL;
-
- int numid = snd_ctl_elem_id_get_numid(id);
- if (numid > 0) {
- if (numid > plughandle->ctlsCount) goto OnErrorExit;
- key= (snd_ctl_ext_key_t) numid -1;
- goto SucessExit;
- }
-
- const char *ctlName= snd_ctl_elem_id_get_name(id);
- if (ctlName == NULL) goto OnErrorExit;
-
- for (int idx=0; idx < plughandle->ctlsCount; idx++) {
- if (! strcmp(ctlName, plughandle->ctls[idx].ctlName)) {
- key = idx;
- goto SucessExit;
- }
- }
-
- SucessExit:
- return key;
-
- OnErrorExit:
- return -1;
-}
-
-static int AfbHalGetAttrib(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, int *type, unsigned int *acc, unsigned int *count) {
- snd_ctl_hal_t *plughandle = (snd_ctl_hal_t*) ext->private_data;
- snd_ctl_elem_info_t *elemInfo = plughandle->infos[key];
- snd_ctl_cb_t callback = plughandle->cbs[key];
-
-
- // search for equivalent NUMID in effective sound card
- if (elemInfo) {
- *type = snd_ctl_elem_info_get_type(elemInfo);
- *count = snd_ctl_elem_info_get_count(elemInfo);
- *acc = SND_CTL_EXT_ACCESS_READWRITE; // Future ToBeDone
- return 0;
- }
-
- if (callback) {
- snd_ctl_get_attrib_t item;
-
- int err = callback(plughandle, CTLCB_GET_ATTRIBUTE, key, &item);
- if (!err) {
- *type = item.type;
- *acc = item.acc;
- *count= item.count;
- }
- return err;
- }
-
- return -1;
-}
-
-static int AfbHalGetIntInfo(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, long *imin, long *imax, long *istep) {
- snd_ctl_hal_t *plughandle = (snd_ctl_hal_t*) ext->private_data;
- snd_ctl_elem_info_t *elemInfo = plughandle->infos[key];
- snd_ctl_cb_t callback = plughandle->cbs[key];
-
- if (elemInfo) {
-
- // Should be normalised to make everything 0-100%
- *imin = (long)snd_ctl_elem_info_get_min(elemInfo);
- *imax = (long)snd_ctl_elem_info_get_min(elemInfo);
- *istep= (long)snd_ctl_elem_info_get_min(elemInfo);
- return 0;
- }
-
- if (callback) {
- snd_ctl_get_int_info_t item;
-
- int err = callback(plughandle, CTLCB_GET_INTEGER_INFO, key, &item);
- if (!err) {
- *imin = item.imin;
- *imax = item.imax;
- *istep= item.istep;
- }
- return err;
- }
-
- return -1;
-}
-
-static int AfbHalGetEnumInfo(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, unsigned int *items) {
- snd_ctl_hal_t *plughandle = (snd_ctl_hal_t*) ext->private_data;
- snd_ctl_elem_info_t *elemInfo = plughandle->infos[key];
- snd_ctl_cb_t callback = plughandle->cbs[key];
-
- if(elemInfo) *items= snd_ctl_elem_info_get_items(elemInfo);
- if(callback) callback(plughandle, CTLCB_GET_ENUMERATED_INFO, key, items);
-
- return 0;
-}
-
-static int AfbHalGetEnumName(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, unsigned int item, char *name, size_t name_max_len) {
- snd_ctl_hal_t *plughandle = (snd_ctl_hal_t*) ext->private_data;
- snd_ctl_elem_info_t *elemInfo = plughandle->infos[key];
-
- //name= snd_ctl_elem_info_get_item_name(elemInfo);
- return 0;
-}
-
-static int AfbHalReadInt(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, long *value) {
- snd_ctl_hal_t *plughandle = (snd_ctl_hal_t*) ext->private_data;
- snd_ctl_elem_info_t *elemInfo = plughandle->infos[key];
-
- return 0;
-}
-
-static int AfbHalReadEnumerate(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, unsigned int *items) {
- snd_ctl_hal_t *plughandle = (snd_ctl_hal_t*) ext->private_data;
-
- return 0;
-}
-
-static int AfbHalWriteInt(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, long *value) {
- snd_ctl_hal_t *plughandle = (snd_ctl_hal_t*) ext->private_data;
-
- return 0;
-}
-
-static int AfbHalWriteEnum(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, unsigned int *items) {
- snd_ctl_hal_t *plughandle = (snd_ctl_hal_t*) ext->private_data;
-
- return 0;
-}
-
-static int AfbHalEventRead(snd_ctl_ext_t *ext, snd_ctl_elem_id_t *id, unsigned int *event_mask) {
- snd_ctl_hal_t *plughandle = (snd_ctl_hal_t*) ext->private_data;
-
- return -EAGAIN;
-}
-
-static int AfbHalElemList(snd_ctl_ext_t *ext, unsigned int offset, snd_ctl_elem_id_t *id) {
- snd_ctl_hal_t *plughandle = (snd_ctl_hal_t*) ext->private_data;
-
- snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
- snd_ctl_elem_id_set_name(id, plughandle->ctls[offset].ctlName);
-
- return 0;
-}
-
-static int AfbHalElemCount(snd_ctl_ext_t *ext) {
- snd_ctl_hal_t *plughandle = (snd_ctl_hal_t*) ext->private_data;
- int count = plughandle->ctlsCount;
- return count;
-}
-
-static void AfbHalClose(snd_ctl_ext_t *ext) {
- snd_ctl_hal_t *plughandle = (snd_ctl_hal_t*) ext->private_data;
- int err;
-
- for (int idx=0; idx < plughandle->ctlsCount; idx++) {
- if (plughandle->ctls[idx].ctlName) free((void*)plughandle->ctls[idx].ctlName);
- }
-
- err = snd_ctl_close(plughandle->ctlDev);
- if (err) SNDERR("Fail Close sndctl: devid=%s err=%s", plughandle->devid, snd_strerror(err));
-
- if (plughandle->devid) free(plughandle->devid);
- free(plughandle);
-}
-
-static snd_ctl_ext_callback_t afbHalCBs = {
- .close = AfbHalClose,
- .elem_count = AfbHalElemCount,
- .elem_list = AfbHalElemList,
- .find_elem = AfbHalElemFind,
- .get_attribute = AfbHalGetAttrib,
- .get_integer_info = AfbHalGetIntInfo,
- .get_enumerated_info = AfbHalGetEnumInfo,
- .get_enumerated_name = AfbHalGetEnumName,
- .read_integer = AfbHalReadInt,
- .read_enumerated = AfbHalReadEnumerate,
- .write_integer = AfbHalWriteInt,
- .write_enumerated = AfbHalWriteEnum,
- .read_event = AfbHalEventRead,
-};
-
-SND_CTL_PLUGIN_DEFINE_FUNC(afbhal) {
-
- snd_config_iterator_t it, next;
- snd_ctl_hal_t *plughandle;
- int err;
- snd_ctl_cb_t AfbHalInitCB;
- const char *libname;
-
- plughandle = calloc(1, sizeof(snd_ctl_hal_t));
-
- snd_config_for_each(it, next, conf) {
- snd_config_t *node = snd_config_iterator_entry(it);
- const char *id;
-
- // ignore comment en empty lines
- if (snd_config_get_id(node, &id) < 0) continue;
- if (strcmp(id, "comment") == 0 || strcmp(id, "type") == 0 || strcmp(id, "hint") == 0) continue;
-
- // devid should point onto a valid sound card
- if (strcmp(id, "devid") == 0) {
- const char *devid;
- if (snd_config_get_string(node, &devid) < 0) {
- SNDERR("Invalid string type for %s", id);
- return -EINVAL;
- }
- plughandle->devid=strdup(devid);
-
- // open control interface for devid
- err = snd_ctl_open(&plughandle->ctlDev, plughandle->devid, 0);
- if (err < 0) {
- SNDERR("Fail to open control device for devid=%s", plughandle->devid);
- return -EINVAL;
- }
- continue;
- }
-
- if (strcmp(id, "cblib") == 0) {
- if (snd_config_get_string(node, &libname) < 0) {
- SNDERR("Invalid libname string for %s", id);
- return -EINVAL;
- }
-
- plughandle->dlHandle= dlopen(libname, RTLD_NOW);
- if (!plughandle->dlHandle) {
- SNDERR("Fail to open callback sharelib=%s error=%s", libname, dlerror());
- return -EINVAL;
- }
-
- AfbHalInitCB = dlsym(plughandle->dlHandle, "AfbHalInitCB");
- if (!AfbHalInitCB) {
- SNDERR("Fail find 'AfbHalInitCB' symbol into callbacks sharelib=%s", libname);
- return -EINVAL;
- }
-
- err = (*AfbHalInitCB)(plughandle,CTLCB_INIT, 0,0);
- if (err) {
- SNDERR("Fail AfbHalInitCB err=%d", err);
- return -EINVAL;
- }
-
- continue;
- }
-
- if (strcmp(id, "ctl") == 0) {
- const char *ctlConf;
- snd_config_type_t ctype;
- snd_config_iterator_t currentCtl, follow;
- snd_config_t *itemConf;
-
- ctype = snd_config_get_type (node);
- if (ctype != SND_CONFIG_TYPE_COMPOUND) {
- snd_config_get_string (node, &ctlConf);
- SNDERR("Invalid compound type for %s", node);
- return -EINVAL;
- }
-
- // loop on each ctl within ctls
- snd_config_for_each (currentCtl, follow, node) {
- snd_config_t *ctlconfig = snd_config_iterator_entry(currentCtl);
- snd_ctl_elem_info_t *elemInfo;
- const char *ctlLabel, *ctlName;
-
- // ignore empty line
- if (snd_config_get_id(ctlconfig, &ctlLabel) < 0) continue;
-
- // each clt should be a valid config compound
- ctype = snd_config_get_type (ctlconfig);
- if (ctype != SND_CONFIG_TYPE_COMPOUND) {
- snd_config_get_string (node, &ctlConf);
- SNDERR("Invalid ctl config for %s", ctlLabel);
- return -EINVAL;
- }
-
- err=snd_config_search(ctlconfig, "ctl", &itemConf);
- if (!err) {
- if (snd_config_get_integer(itemConf, (long*)&plughandle->ctls[plughandle->ctlsCount].ctlNumid) < 0) {
- SNDERR("Not Integer: ctl:%s numid should be a valid integer", ctlLabel);
- return -EINVAL;
- }
-
- // Make sure than numid is valid on slave snd card
- snd_ctl_elem_info_malloc(&elemInfo);
- snd_ctl_elem_info_set_numid(elemInfo, (int)plughandle->ctls[plughandle->ctlsCount].ctlNumid);
- plughandle->infos[plughandle->ctlsCount]= elemInfo;
-
- err = snd_ctl_elem_info(plughandle->ctlDev, elemInfo);
- if (err) {
- SNDERR("Not Found: 'numid=%d' for 'devid=%s'", plughandle->ctls[plughandle->ctlsCount].ctlNumid, plughandle->devid);
- return -EINVAL;
- }
- }
-
- err=snd_config_search(ctlconfig, "ctlcb", &itemConf);
- if (!err) {
- const char *funcname;
- void *funcaddr;
-
- if (snd_config_get_string(itemConf, &funcname) < 0) {
- SNDERR("Not string: ctl:%s cbname should be a valid string", ctlLabel);
- return -EINVAL;
- }
-
- if (funcname[0] != '@') {
- SNDERR("Not string: ctl:%s cbname=%s should be prefixed with '@' ", ctlLabel, funcname);
- return -EINVAL;
- }
-
- if (!plughandle->dlHandle) {
- SNDERR("No CB: ctl:%s cblib:/my/libcallback missing from asoundrc", ctlLabel);
- return -EINVAL;
- }
-
- funcaddr = dlsym(plughandle->dlHandle, &funcname[1]);
- if (!funcaddr) {
- SNDERR("NotFound CB: ctl:%s cbname='%s' no symbol into %s", ctlLabel, &funcname[1], libname);
- return -EINVAL;
- }
- plughandle->cbs[plughandle->ctlsCount]=funcaddr;
- }
-
- err=snd_config_search(ctlconfig, "name", &itemConf);
- if (err) {
- SNDERR("Not Found: 'name' mandatory in ctl config");
- return -EINVAL;
- }
-
- if (snd_config_get_string(itemConf, &ctlName) < 0) {
- SNDERR("Not String: ctl:%s 'name' should be a valie string", ctlLabel);
- return -EINVAL;
- }
- plughandle->ctls[plughandle->ctlsCount].ctlName = strdup(ctlName);
-
- // move to next ctl if any
- plughandle->ctlsCount++;
- } // end for each ctl
- continue;
- }
- SNDERR("Unknown field %s", id);
- return -EINVAL;
- }
-
-
-
- // Create ALSA control plugin structure
- plughandle->ext.version = SND_CTL_EXT_VERSION;
- plughandle->ext.card_idx = 0; /* FIXME */
- strcpy(plughandle->ext.id , "AFB-HAL-CTL");
- strcpy(plughandle->ext.driver , "AFB-HAL");
- strcpy(plughandle->ext.name , "AFB-HAL Control Plugin");
- strcpy(plughandle->ext.mixername, "AFB-HAL Mixer Plugin");
- strcpy(plughandle->ext.longname , "Automotive-Linux Sound Abstraction Control Plugin");
- plughandle->ext.poll_fd = -1;
- plughandle->ext.callback = &afbHalCBs;
- plughandle->ext.private_data = (void*)plughandle;
-
-
-
- err = snd_ctl_ext_create(&plughandle->ext, name, mode);
- if (err < 0) {
- SNDERR("Fail Register sndctl for devid=%s", plughandle->devid);
- goto OnErrorExit;
- }
-
- // Plugin register controls update handlep before exiting
- *handlep = plughandle->ext.handle;
- return 0;
-
-OnErrorExit:
- free(plughandle);
- return -1;
-}
-
-SND_CTL_PLUGIN_SYMBOL(afbhal);
diff --git a/HAL-afb/HAL-plugin/README.md b/HAL-afb/HAL-plugin/README.md
deleted file mode 100644
index 1c1e7a2..0000000
--- a/HAL-afb/HAL-plugin/README.md
+++ /dev/null
@@ -1,44 +0,0 @@
-Hal-Plugin
-
-Object: provide an ALSA a HAL (Hardware Abstraction Layer) to automotive sound cards
-Status: Current version is proof of concept and not a usable product
-Author: Fulup Ar Foll
-Date : June-2017
-
-HAL-plugin allows:
- - to expose any existing NUMID under a customized label name, this is order to abstract sound card config.
- - to add non alsa NUMID supported through a callback mechanism (eg: volume rampdown, power off, ...)
-
-installation
- - Plugin should be placed where ever alsaplugins are located (typically: /usr/share/alsa-lib)
- - Callback sharelib directory should be declare in $LD_LIBRARY_PATH
-
-Config
-```
-cat ~/.asoundrc
- ctl.agl_hal {
- type afbhal
- devid "hw:4"
- cblib "afbhal_cb_sample.so"
- ctls {
- # ctlLabel {numid integer name "Alsa Ctl Name"}
- MasterSwitch { numid 4 name "My_First_Control" }
- MasterVol { numid 5 name "My_Second_Control" }
- CB_sample { ctlcb @AfbHalSampleCB name "My_Sample_Callback"}
- }
- pcm.agl_hal {
- type copy # Copy PCM
- slave "hw:4" # Slave name
- }
-```
-
-With such a config file
- - numid=4 from sndcard=hw:4 is renamed "My_First_Control"
- - numid=4 from sndcard=hw:4 is renamed "My_Second_Control"
- - numid=4 will call AfbHalSampleCB from afbhal_cb_sample.so
-
-Note: to really implement a usable HAL at minimum every ALSA call should be implemented and read/write of values should be normalised from 0 to 100% with a step of 1.
-
-Conclusion: This demonstrate that implementing a HAL that both abstract ALSA get/set and enable non ALSA support is possible at an acceptable cost
-without having to hack ALSA source code. The beauty of the model is than it is fully transparent to any ALSA application. The limit is that the plugin is loaded
-within every application context, thus interaction with an external event loop remains complete as well as conflict management in case of share resources.
diff --git a/HAL-afb/HDA-intel/IntelHdaHAL.c b/HAL-afb/HDA-intel/IntelHdaHAL.c
index f7aec59..f5c260e 100644
--- a/HAL-afb/HDA-intel/IntelHdaHAL.c
+++ b/HAL-afb/HDA-intel/IntelHdaHAL.c
@@ -27,48 +27,52 @@
// Default Values for MasterVolume Ramping
-STATIC halVolRampT volRampMaster= {
- .mode = RAMP_VOL_NORMAL,
- .slave = Master_Playback_Volume,
- .delay = 100*1000, // ramping delay in us
- .stepDown=1,
- .stepUp =1,
+STATIC halVolRampT volRampMaster = {
+ .mode = RAMP_VOL_NORMAL,
+ .slave = Master_Playback_Volume,
+ .delay = 100 * 1000, // ramping delay in us
+ .stepDown = 1,
+ .stepUp = 1,
};
// Map HAL hight sndctl with Alsa numid and optionally with a custom callback for non Alsa supported functionalities.
-STATIC alsaHalMapT alsaHalMap[]= {
- { .tag=Master_Playback_Volume, . ctl={ .name="Master Playback Volume" } },
- { .tag=PCM_Playback_Volume , .ctl={ .name="PCM Playback Volume" } },
- { .tag=PCM_Playback_Switch , .ctl={ .name="Master Playback Switch" } },
- { .tag=Capture_Volume , .ctl={ .name="Capture Volume" } },
+STATIC alsaHalMapT alsaHalMap[] = {
+ { .tag = Master_Playback_Volume, . ctl =
+ { .name = "Master Playback Volume"}},
+ { .tag = PCM_Playback_Volume, .ctl =
+ { .name = "PCM Playback Volume"}},
+ { .tag = PCM_Playback_Switch, .ctl =
+ { .name = "Master Playback Switch"}},
+ { .tag = Capture_Volume, .ctl =
+ { .name = "Capture Volume"}},
- { .tag=Vol_Ramp , .cb={.callback=volumeRamp, .handle=&volRampMaster}, .info="ramp volume linearly according to current ramp setting",
- .ctl={.numid=0, .type=SND_CTL_ELEM_TYPE_INTEGER, .count=1, .minval=0, .maxval=100, .step=1, .name="Hal-VolRamp"}
- },
-
- { .tag=EndHalCrlTag} /* marker for end of the array */
-} ;
+ { .tag = Master_Playback_Volume, .cb =
+ {.callback = volumeRamp, .handle = &volRampMaster}, .info = "ramp volume linearly according to current ramp setting",
+ .ctl =
+ {.numid = 0, .type = SND_CTL_ELEM_TYPE_INTEGER, .count = 1, .minval = 0, .maxval = 100, .step = 1, .name = "Hal-VolRamp"}},
-// HAL sound card mapping info
-STATIC alsaHalSndCardT alsaHalSndCard = {
- .name = "HDA Intel PCH", // WARNING: name MUST match with 'aplay -l'
- .info = "Hardware Abstraction Layer for IntelHDA sound card",
- .ctls = alsaHalMap,
+ { .tag = EndHalCrlTag} /* marker for end of the array */
};
+// HAL sound card mapping info
+STATIC alsaHalSndCardT alsaHalSndCard = {
+ .name = "HDA Intel PCH", // WARNING: name MUST match with 'aplay -l'
+ .info = "Hardware Abstraction Layer for IntelHDA sound card",
+ .ctls = alsaHalMap,
+};
-STATIC int sndServiceInit () {
+STATIC int sndServiceInit() {
int err;
- AFB_DEBUG ("IntelHalBinding Init");
+ AFB_DEBUG("IntelHal Binding Init");
- err = halServiceInit (afbBindingV2.api, &alsaHalSndCard);
+ err = halServiceInit(afbBindingV2.api, &alsaHalSndCard);
return err;
}
// API prefix should be unique for each snd card
PUBLIC const struct afb_binding_v2 afbBindingV2 = {
- .api = "intel-hda",
- .init = sndServiceInit,
- .verbs = halServiceApi,
+ .api = "intel-hda",
+ .init = sndServiceInit,
+ .verbs = halServiceApi,
.onevent = halServiceEvent,
};
diff --git a/HAL-afb/Unicens-USB/CMakeLists.txt b/HAL-afb/Jabra-Solemate/CMakeLists.txt
index 5ca563b..9504175 100644
--- a/HAL-afb/Unicens-USB/CMakeLists.txt
+++ b/HAL-afb/Jabra-Solemate/CMakeLists.txt
@@ -18,10 +18,10 @@
# Add target to project dependency list
-PROJECT_TARGET_ADD(hal-unicens-usb)
+PROJECT_TARGET_ADD(hal-jabra-usb)
# Define project Targets
- ADD_LIBRARY(${TARGET_NAME} MODULE UnicensHAL.c UnicensVol.c)
+ ADD_LIBRARY(${TARGET_NAME} MODULE JabraUsbHAL.c)
# Binder exposes a unique public entry point
SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
@@ -32,7 +32,7 @@ PROJECT_TARGET_ADD(hal-unicens-usb)
)
# Library dependencies (include updates automatically)
- TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ TARGET_LINK_LIBRARIES(${TARGET_NAME}
hal-interface
audio-interface
)
diff --git a/HAL-afb/Jabra-Solemate/JabraUsbHAL.c b/HAL-afb/Jabra-Solemate/JabraUsbHAL.c
new file mode 100644
index 0000000..f3753ec
--- /dev/null
+++ b/HAL-afb/Jabra-Solemate/JabraUsbHAL.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2016 "IoT.bzh"
+ * Author Fulup Ar Foll <fulup@iot.bzh>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ * To find out which control your sound card uses
+ * aplay -l # Check sndcard name name in between []
+ * amixer -D hw:USB controls # get supported controls
+ * amixer -Dhw:USB cget name=Power-Switch
+ * amixer -Dhw:USB cset name=Power-Switch true
+ *
+ */
+#define _GNU_SOURCE
+#include "hal-interface.h"
+#include "audio-interface.h"
+
+// Define few private tag for not standard functions
+#define PCM_Volume_Multimedia 1000
+#define PCM_Volume_Navigation 1001
+#define PCM_Volume_Emergency 1002
+
+// Default Values for MasterVolume Ramping
+STATIC halVolRampT volRampMaster= {
+ .mode = RAMP_VOL_NORMAL,
+ .slave = Master_Playback_Volume,
+ .delay = 100*1000, // ramping delay in us
+ .stepDown=1,
+ .stepUp =1,
+};
+
+STATIC halVolRampT volRampMultimedia= {
+ .slave = PCM_Volume_Multimedia,
+ .delay = 100*1000, // ramping delay in us
+ .stepDown= 2,
+ .stepUp = 1,
+};
+
+STATIC halVolRampT volRampNavigation= {
+ .slave = PCM_Volume_Navigation,
+ .delay = 100*1000, // ramping delay in us
+ .stepDown= 4,
+ .stepUp = 2,
+};
+// Default Values for MasterVolume Ramping
+STATIC halVolRampT volRampEmergency= {
+ .slave = PCM_Volume_Emergency,
+ .delay = 50*1000, // ramping delay in us
+ .stepDown= 6,
+ .stepUp = 3,
+};
+
+// Map HAL hight sndctl with Alsa numid and optionally with a custom callback for non Alsa supported functionalities.
+STATIC alsaHalMapT alsaHalMap[]= {
+ { .tag=Master_Playback_Volume, . ctl={.name="PCM Playback Volume" } },
+ { .tag=PCM_Playback_Volume , .ctl={.name="PCM Playback Volume" } },
+ { .tag=PCM_Playback_Switch , .ctl={.name="PCM Playback Switch" } },
+ { .tag=Capture_Volume , .ctl={.name="Mic Capture Volume" } },
+
+ // Sound card does not have hardware volume ramping
+ { .tag=Master_Playback_Ramp , .cb={.callback=volumeRamp, .handle=&volRampMaster}, .info="ramp volume linearly according to current ramp setting",
+ .ctl={.numid=CTL_AUTO, .type=SND_CTL_ELEM_TYPE_INTEGER, .count=1, .minval=0, .maxval=100, .step=1, .name="Rampup Master"}
+ },
+
+ // Implement Rampup Volume for Virtual Channels
+ { .tag=Multimedia_Playback_Volume, .cb={.callback=volumeRamp, .handle=&volRampMultimedia}, .info="Rampup Multimedia Volume",
+ .ctl={.numid=CTL_AUTO, .type=SND_CTL_ELEM_TYPE_INTEGER, .name="Playback Multimedia Ramp"}
+ },
+ { .tag=Navigation_Playback_Volume, .cb={.callback=volumeRamp, .handle=&volRampNavigation}, .info="RampUp Navigation Volume",
+ .ctl={.numid=CTL_AUTO, .type=SND_CTL_ELEM_TYPE_INTEGER,.name="Playback Navigation Ramp"}
+ },
+ { .tag=Emergency_Playback_Volume, .cb={.callback=volumeRamp, .handle=&volRampEmergency}, .info="Rampup Emergency Volume",
+ .ctl={.numid=CTL_AUTO, .type=SND_CTL_ELEM_TYPE_INTEGER,.name="Playback Emergency Ramp"}
+ },
+
+ // Sound Card does not support hardware channel volume mixer (note softvol default range 0-256)
+ { .tag=PCM_Volume_Multimedia, .info="Playback Multimedia Softvol",
+ .ctl={.numid=CTL_AUTO, .type=SND_CTL_ELEM_TYPE_INTEGER, .count=2, .maxval=255, .value=200, .name="Playback Multimedia"}
+ },
+ { .tag=PCM_Volume_Navigation, .info="Playback Navigation Softvol",
+ .ctl={.numid=CTL_AUTO, .type=SND_CTL_ELEM_TYPE_INTEGER, .count=2, .maxval=255,.value=200, .name="Playback Navigation"}
+ },
+ { .tag=PCM_Volume_Emergency, .info="Playback Emergency Softvol",
+ .ctl={.numid=CTL_AUTO, .type=SND_CTL_ELEM_TYPE_INTEGER, .count=2, .maxval=255, .value=200, .name="Playback Emergency"}
+ },
+
+
+ { .tag=EndHalCrlTag} /* marker for end of the array */
+} ;
+
+// HAL sound card mapping info
+STATIC alsaHalSndCardT alsaHalSndCard = {
+ .name = "Jabra SOLEMATE v1.34.0", // WARNING: name MUST match with 'aplay -l'
+ .info = "Hardware Abstraction Layer for Jabra Solamte USB speakers",
+ .ctls = alsaHalMap,
+ .volumeCB = NULL, // use default volume normalisation function
+};
+
+
+STATIC int sndServiceInit () {
+ int err;
+ err = halServiceInit (afbBindingV2.api, &alsaHalSndCard);
+ return err;
+}
+
+// API prefix should be unique for each snd card
+PUBLIC const struct afb_binding_v2 afbBindingV2 = {
+ .api = "jabra-usb",
+ .init = sndServiceInit,
+ .verbs = halServiceApi,
+ .onevent = halServiceEvent,
+};
diff --git a/HAL-afb/Scarlett-Focusrite/CMakeLists.txt b/HAL-afb/Scarlett-Focusrite/CMakeLists.txt
index 4cbac19..93752a7 100644
--- a/HAL-afb/Scarlett-Focusrite/CMakeLists.txt
+++ b/HAL-afb/Scarlett-Focusrite/CMakeLists.txt
@@ -21,7 +21,7 @@
PROJECT_TARGET_ADD(hal-scalett-usb)
# Define project Targets
- ADD_LIBRARY(hal-scalett-usb MODULE ScarlettUsbHAL.c)
+ ADD_LIBRARY(${TARGET_NAME} MODULE ScarlettUsbHAL.c)
# Binder exposes a unique public entry point
SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
diff --git a/HAL-afb/Scarlett-Focusrite/ScarlettUsbHAL.c b/HAL-afb/Scarlett-Focusrite/ScarlettUsbHAL.c
index dd4499e..9b31c96 100644
--- a/HAL-afb/Scarlett-Focusrite/ScarlettUsbHAL.c
+++ b/HAL-afb/Scarlett-Focusrite/ScarlettUsbHAL.c
@@ -57,7 +57,7 @@ STATIC alsaHalMapT alsaHalMap[]= {
{ .tag=Vol_Ramp_Set_Up , .cb={.callback=volumeRamp, .handle=&volRampMaster}, .info="set linear step up ramp [default 10]",
.ctl={.numid=0, .type=SND_CTL_ELEM_TYPE_INTEGER, .count=1, .minval=0, .maxval=100, .step=1, .value=10, .name="Hal-VolRamp-Step-Up"}
},
- { .tag=Vol_Ramp , .cb={.callback=volumeRamp, .handle=&volRampMaster}, .info="ramp volume linearly according to current ramp setting",
+ { .tag=Master_Playback_Volume , .cb={.callback=volumeRamp, .handle=&volRampMaster}, .info="ramp volume linearly according to current ramp setting",
.ctl={.numid=0, .type=SND_CTL_ELEM_TYPE_INTEGER, .count=1, .minval=0, .maxval=100, .step=1, .name="Hal-VolRamp"}
},
@@ -75,7 +75,7 @@ STATIC alsaHalSndCardT alsaHalSndCard = {
STATIC int sndServiceInit () {
int err;
- AFB_DEBUG ("IntelHalBinding Init");
+ AFB_DEBUG ("Scarlett Binding Init");
err = halServiceInit (afbBindingV2.api, &alsaHalSndCard);
return err;
diff --git a/HAL-afb/Unicens-USB/UnicensHAL.c b/HAL-afb/Unicens-USB/UnicensHAL.c
deleted file mode 100644
index 9a42afd..0000000
--- a/HAL-afb/Unicens-USB/UnicensHAL.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2016 "IoT.bzh"
- * Author Fulup Ar Foll <fulup@iot.bzh>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *
- * To find out which control your sound card uses
- * aplay -l # Check sndcard name name in between []
- * amixer -D hw:xx controls # get supported controls
- * amixer -D "hw:3" cget numid=xx # get control settings
- *
- */
-#define _GNU_SOURCE
-#include "hal-interface.h"
-#include "audio-interface.h"
-
-
-
-// Map HAL hight sndctl with Alsa numid and optionally with a custom callback for non Alsa supported functionalities.
-STATIC alsaHalMapT alsaHalMap[]= {
- { .tag=Master_Playback_Volume, .ctl={.numid=04 } },
- { .tag=PCM_Playback_Volume , .ctl={.numid=06 } },
- { .tag=PCM_Playback_Switch , .ctl={.numid=05 } },
- { .tag=Capture_Volume , .ctl={.numid=12 } },
-
- { .tag=EndHalCrlTag} /* marker for end of the array */
-} ;
-
-// HAL sound card mapping info
-STATIC alsaHalSndCardT alsaHalSndCard = {
- .name = "HDA Intel PCH", // WARNING: name MUST match with 'aplay -l'
- .info = "Hardware Abstraction Layer for IntelHDA sound card",
- .ctls = alsaHalMap,
-};
-
-
-STATIC int sndServiceInit () {
- int err;
- AFB_DEBUG ("IntelHalBinding Init");
-
- err = halServiceInit (afbBindingV2.api, &alsaHalSndCard);
- return err;
-}
-
-// API prefix should be unique for each snd card
-PUBLIC const struct afb_binding_v2 afbBindingV2 = {
- .api = "unicens-usb",
- .init = sndServiceInit,
- .verbs = halServiceApi,
- .onevent = halServiceEvent,
-};
diff --git a/HAL-afb/Unicens-USB/UnicensVol.c b/HAL-afb/Unicens-USB/UnicensVol.c
deleted file mode 100644
index cf4f497..0000000
--- a/HAL-afb/Unicens-USB/UnicensVol.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2016 "IoT.bzh"
- * Author Fulup Ar Foll <fulup@iot.bzh>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *
- * To find out which control your sound card uses
- * aplay -l # Check sndcard name name in between []
- * amixer -D hw:xx controls # get supported controls
- * amixer -D "hw:3" cget numid=xx # get control settings
- *
- */
-#define _GNU_SOURCE
-#include "hal-interface.h"
-#include "audio-interface.h"
-
-STATIC json_object* MasterOnOff (alsaHalCtlMapT *control, void* handle, json_object *valJ) {
- json_object *reponseJ;
-
- AFB_INFO ("Power Set value=%s", json_object_get_string(valJ));
-
- reponseJ=json_object_new_object();
- json_object_object_add (reponseJ, "Callback", json_object_new_string("Hello From HAL"));
-
- return reponseJ;
-}