Honour max_output_db setting even when ignore_volume_control is true. Spell out "Shairport Sync" in the Home app information.
This commit is contained in:
@@ -1760,27 +1760,25 @@ void *player_thread_func(void *arg) {
|
||||
// successive rtptimes, at worst
|
||||
|
||||
conn->output_sample_ratio = config.output_rate / conn->input_rate;
|
||||
|
||||
|
||||
// Sign extending rtptime calculations to 64 bit is needed from time to time.
|
||||
|
||||
// The standard rtptime is unsigned 32 bits,
|
||||
// so you can do modulo 2^32 difference calculations
|
||||
// and get a signed result simply by typing the result as a signed 32-bit number.
|
||||
// Sign extending rtptime calculations to 64 bit is needed from time to time.
|
||||
|
||||
// So long as you can be sure the numbers are within 2^31 of each other,
|
||||
// the sign of the result calculated in this way indicates the order of the operands.
|
||||
// For example, if you subtract a from b and the result is positive, you can conclude
|
||||
// b is the same as or comes after a in module 2^32 order.
|
||||
// The standard rtptime is unsigned 32 bits,
|
||||
// so you can do modulo 2^32 difference calculations
|
||||
// and get a signed result simply by typing the result as a signed 32-bit number.
|
||||
|
||||
// We want to do the same with the rtptime calculations for multiples of
|
||||
// the rtptimes (1, 2, 4 or 8 times), and we want to do this in signed 64-bit/
|
||||
// Therefore we need to sign extend these modulo 2^32, 2^33, 2^34, or 2^35 bit unsigned
|
||||
// numbers on the same basis.
|
||||
// So long as you can be sure the numbers are within 2^31 of each other,
|
||||
// the sign of the result calculated in this way indicates the order of the operands.
|
||||
// For example, if you subtract a from b and the result is positive, you can conclude
|
||||
// b is the same as or comes after a in module 2^32 order.
|
||||
|
||||
// That is what the output_rtptime_sign_bit, output_rtptime_mask, output_rtptime_mask_not and
|
||||
// output_rtptime_sign_mask are for -- see later, calculating the sync error.
|
||||
// We want to do the same with the rtptime calculations for multiples of
|
||||
// the rtptimes (1, 2, 4 or 8 times), and we want to do this in signed 64-bit/
|
||||
// Therefore we need to sign extend these modulo 2^32, 2^33, 2^34, or 2^35 bit unsigned
|
||||
// numbers on the same basis.
|
||||
|
||||
// That is what the output_rtptime_sign_bit, output_rtptime_mask, output_rtptime_mask_not and
|
||||
// output_rtptime_sign_mask are for -- see later, calculating the sync error.
|
||||
|
||||
int output_rtptime_sign_bit;
|
||||
switch (conn->output_sample_ratio) {
|
||||
@@ -2022,7 +2020,6 @@ void *player_thread_func(void *arg) {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_AIRPLAY_2
|
||||
if (conn->timing_type == ts_ntp) {
|
||||
#endif
|
||||
@@ -2940,45 +2937,46 @@ void player_volume_without_notification(double airplay_volume, rtsp_conn_info *c
|
||||
// if it's both, we haven't decided whether hw or sw should be on top
|
||||
// we have to consider the settings ignore_volume_control and mute.
|
||||
|
||||
if (config.ignore_volume_control == 0) {
|
||||
if (airplay_volume == -144.0) {
|
||||
if (airplay_volume == -144.0) {
|
||||
|
||||
if ((config.output->mute) && (config.output->mute(1) == 0))
|
||||
debug(2,
|
||||
"player_volume_without_notification: volume mode is %d, airplay_volume is %f, "
|
||||
"hardware mute is enabled.",
|
||||
volume_mode, airplay_volume);
|
||||
else {
|
||||
conn->software_mute_enabled = 1;
|
||||
debug(2,
|
||||
"player_volume_without_notification: volume mode is %d, airplay_volume is %f, "
|
||||
"software mute is enabled.",
|
||||
volume_mode, airplay_volume);
|
||||
}
|
||||
if ((config.output->mute) && (config.output->mute(1) == 0))
|
||||
debug(2,
|
||||
"player_volume_without_notification: volume mode is %d, airplay_volume is %f, "
|
||||
"hardware mute is enabled.",
|
||||
volume_mode, airplay_volume);
|
||||
else {
|
||||
conn->software_mute_enabled = 1;
|
||||
debug(2,
|
||||
"player_volume_without_notification: volume mode is %d, airplay_volume is %f, "
|
||||
"software mute is enabled.",
|
||||
volume_mode, airplay_volume);
|
||||
}
|
||||
|
||||
} else {
|
||||
int32_t max_db = 0, min_db = 0;
|
||||
switch (volume_mode) {
|
||||
case vol_hw_only:
|
||||
max_db = hw_max_db;
|
||||
min_db = hw_min_db;
|
||||
break;
|
||||
case vol_sw_only:
|
||||
max_db = sw_max_db;
|
||||
min_db = sw_min_db;
|
||||
break;
|
||||
case vol_both:
|
||||
// debug(1, "dB range passed is hw: %d, sw: %d, total: %d", hw_max_db - hw_min_db,
|
||||
// sw_max_db - sw_min_db, (hw_max_db - hw_min_db) + (sw_max_db - sw_min_db));
|
||||
max_db =
|
||||
(hw_max_db - hw_min_db) + (sw_max_db - sw_min_db); // this should be the range requested
|
||||
min_db = 0;
|
||||
break;
|
||||
default:
|
||||
debug(1, "player_volume_without_notification: error: not in a volume mode");
|
||||
break;
|
||||
}
|
||||
double scaled_attenuation = max_db;
|
||||
if (config.ignore_volume_control == 0) {
|
||||
|
||||
} else {
|
||||
int32_t max_db = 0, min_db = 0;
|
||||
switch (volume_mode) {
|
||||
case vol_hw_only:
|
||||
max_db = hw_max_db;
|
||||
min_db = hw_min_db;
|
||||
break;
|
||||
case vol_sw_only:
|
||||
max_db = sw_max_db;
|
||||
min_db = sw_min_db;
|
||||
break;
|
||||
case vol_both:
|
||||
// debug(1, "dB range passed is hw: %d, sw: %d, total: %d", hw_max_db - hw_min_db,
|
||||
// sw_max_db - sw_min_db, (hw_max_db - hw_min_db) + (sw_max_db - sw_min_db));
|
||||
max_db =
|
||||
(hw_max_db - hw_min_db) + (sw_max_db - sw_min_db); // this should be the range requested
|
||||
min_db = 0;
|
||||
break;
|
||||
default:
|
||||
debug(1, "player_volume_without_notification: error: not in a volume mode");
|
||||
break;
|
||||
}
|
||||
double scaled_attenuation = 0.0;
|
||||
if (config.volume_control_profile == VCP_standard)
|
||||
scaled_attenuation = vol2attn(airplay_volume, max_db, min_db); // no cancellation points
|
||||
else if (config.volume_control_profile == VCP_flat)
|
||||
@@ -2986,116 +2984,122 @@ void player_volume_without_notification(double airplay_volume, rtsp_conn_info *c
|
||||
flat_vol2attn(airplay_volume, max_db, min_db); // no cancellation points
|
||||
else
|
||||
debug(1, "player_volume_without_notification: unrecognised volume control profile");
|
||||
|
||||
// so here we have the scaled attenuation. If it's for hw or sw only, it's straightforward.
|
||||
double hardware_attenuation = 0.0;
|
||||
double software_attenuation = 0.0;
|
||||
|
||||
switch (volume_mode) {
|
||||
case vol_hw_only:
|
||||
hardware_attenuation = scaled_attenuation;
|
||||
break;
|
||||
case vol_sw_only:
|
||||
software_attenuation = scaled_attenuation;
|
||||
break;
|
||||
case vol_both:
|
||||
// here, we now the attenuation required, so we have to apportion it to the sw and hw mixers
|
||||
// if we give the hw priority, that means when lowering the volume, set the hw volume to its
|
||||
// lowest
|
||||
// before using the sw attenuation.
|
||||
// similarly, if we give the sw priority, that means when lowering the volume, set the sw
|
||||
// volume to its lowest
|
||||
// before using the hw attenuation.
|
||||
// one imagines that hw priority is likely to be much better
|
||||
// if (config.volume_range_hw_priority) {
|
||||
if (config.volume_range_hw_priority != 0) {
|
||||
// hw priority
|
||||
if ((sw_max_db - sw_min_db) > scaled_attenuation) {
|
||||
software_attenuation = sw_min_db + scaled_attenuation;
|
||||
hardware_attenuation = hw_min_db;
|
||||
} else {
|
||||
software_attenuation = sw_max_db;
|
||||
hardware_attenuation = hw_min_db + scaled_attenuation - (sw_max_db - sw_min_db);
|
||||
}
|
||||
} else {
|
||||
// sw priority
|
||||
if ((hw_max_db - hw_min_db) > scaled_attenuation) {
|
||||
hardware_attenuation = hw_min_db + scaled_attenuation;
|
||||
software_attenuation = sw_min_db;
|
||||
} else {
|
||||
hardware_attenuation = hw_max_db;
|
||||
software_attenuation = sw_min_db + scaled_attenuation - (hw_max_db - hw_min_db);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
debug(1, "player_volume_without_notification: error: not in a volume mode");
|
||||
break;
|
||||
}
|
||||
|
||||
if (((volume_mode == vol_hw_only) || (volume_mode == vol_both)) && (config.output->volume)) {
|
||||
config.output->volume(hardware_attenuation); // otherwise set the output to the lowest value
|
||||
// debug(1,"Hardware attenuation set to %f for airplay volume of
|
||||
// %f.",hardware_attenuation,airplay_volume);
|
||||
if (volume_mode == vol_hw_only)
|
||||
conn->fix_volume = 0x10000;
|
||||
}
|
||||
|
||||
if ((volume_mode == vol_sw_only) || (volume_mode == vol_both)) {
|
||||
double temp_fix_volume = 65536.0 * pow(10, software_attenuation / 2000);
|
||||
// debug(1,"Software attenuation set to %f, i.e %f out of 65,536, for airplay volume of
|
||||
// %f",software_attenuation,temp_fix_volume,airplay_volume);
|
||||
|
||||
conn->fix_volume = temp_fix_volume;
|
||||
|
||||
// if (config.loudness)
|
||||
loudness_set_volume(software_attenuation / 100);
|
||||
}
|
||||
|
||||
if (config.logOutputLevel) {
|
||||
inform("Output Level set to: %.2f dB.", scaled_attenuation / 100.0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_METADATA
|
||||
// here, send the 'pvol' metadata message when the airplay volume information
|
||||
// is being used by shairport sync to control the output volume
|
||||
char dv[128];
|
||||
memset(dv, 0, 128);
|
||||
if (volume_mode == vol_both) {
|
||||
// normalise the maximum output to the hardware device's max output
|
||||
snprintf(dv, 127, "%.2f,%.2f,%.2f,%.2f", airplay_volume,
|
||||
(scaled_attenuation - max_db + hw_max_db) / 100.0,
|
||||
(min_db - max_db + hw_max_db) / 100.0, (max_db - max_db + hw_max_db) / 100.0);
|
||||
} else {
|
||||
snprintf(dv, 127, "%.2f,%.2f,%.2f,%.2f", airplay_volume, scaled_attenuation / 100.0,
|
||||
min_db / 100.0, max_db / 100.0);
|
||||
}
|
||||
send_ssnc_metadata('pvol', dv, strlen(dv), 1);
|
||||
#endif
|
||||
|
||||
if (config.output->mute)
|
||||
config.output->mute(0);
|
||||
conn->software_mute_enabled = 0;
|
||||
|
||||
debug(2,
|
||||
"player_volume_without_notification: volume mode is %d, airplay volume is %f, "
|
||||
"software_attenuation: %f, hardware_attenuation: %f, muting "
|
||||
"is disabled.",
|
||||
volume_mode, airplay_volume, software_attenuation, hardware_attenuation);
|
||||
}
|
||||
}
|
||||
// so here we have the scaled attenuation. If it's for hw or sw only, it's straightforward.
|
||||
double hardware_attenuation = 0.0;
|
||||
double software_attenuation = 0.0;
|
||||
|
||||
switch (volume_mode) {
|
||||
case vol_hw_only:
|
||||
hardware_attenuation = scaled_attenuation;
|
||||
break;
|
||||
case vol_sw_only:
|
||||
software_attenuation = scaled_attenuation;
|
||||
break;
|
||||
case vol_both:
|
||||
// here, we now the attenuation required, so we have to apportion it to the sw and hw mixers
|
||||
// if we give the hw priority, that means when lowering the volume, set the hw volume to its
|
||||
// lowest
|
||||
// before using the sw attenuation.
|
||||
// similarly, if we give the sw priority, that means when lowering the volume, set the sw
|
||||
// volume to its lowest
|
||||
// before using the hw attenuation.
|
||||
// one imagines that hw priority is likely to be much better
|
||||
// if (config.volume_range_hw_priority) {
|
||||
if (config.volume_range_hw_priority != 0) {
|
||||
// hw priority
|
||||
if ((sw_max_db - sw_min_db) > scaled_attenuation) {
|
||||
software_attenuation = sw_min_db + scaled_attenuation;
|
||||
hardware_attenuation = hw_min_db;
|
||||
} else {
|
||||
software_attenuation = sw_max_db;
|
||||
hardware_attenuation = hw_min_db + scaled_attenuation - (sw_max_db - sw_min_db);
|
||||
}
|
||||
} else {
|
||||
// sw priority
|
||||
if ((hw_max_db - hw_min_db) > scaled_attenuation) {
|
||||
hardware_attenuation = hw_min_db + scaled_attenuation;
|
||||
software_attenuation = sw_min_db;
|
||||
} else {
|
||||
hardware_attenuation = hw_max_db;
|
||||
software_attenuation = sw_min_db + scaled_attenuation - (hw_max_db - hw_min_db);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
debug(1, "player_volume_without_notification: error: not in a volume mode");
|
||||
break;
|
||||
}
|
||||
|
||||
if (((volume_mode == vol_hw_only) || (volume_mode == vol_both)) && (config.output->volume)) {
|
||||
config.output->volume(hardware_attenuation); // otherwise set the output to the lowest value
|
||||
// debug(1,"Hardware attenuation set to %f for airplay volume of
|
||||
// %f.",hardware_attenuation,airplay_volume);
|
||||
if (volume_mode == vol_hw_only)
|
||||
conn->fix_volume = 0x10000;
|
||||
}
|
||||
|
||||
if ((volume_mode == vol_sw_only) || (volume_mode == vol_both)) {
|
||||
double temp_fix_volume = 65536.0 * pow(10, software_attenuation / 2000);
|
||||
|
||||
if (config.ignore_volume_control == 0)
|
||||
debug(2, "Software attenuation set to %f, i.e %f out of 65,536, for airplay volume of %f",
|
||||
software_attenuation, temp_fix_volume, airplay_volume);
|
||||
else
|
||||
debug(2, "Software attenuation set to %f, i.e %f out of 65,536. Volume control is ignored.",
|
||||
software_attenuation, temp_fix_volume);
|
||||
|
||||
conn->fix_volume = temp_fix_volume;
|
||||
|
||||
// if (config.loudness)
|
||||
loudness_set_volume(software_attenuation / 100);
|
||||
}
|
||||
|
||||
if (config.logOutputLevel) {
|
||||
inform("Output Level set to: %.2f dB.", scaled_attenuation / 100.0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_METADATA
|
||||
else {
|
||||
// here, send the 'pvol' metadata message when the airplay volume information
|
||||
// is being used by shairport sync to control the output volume
|
||||
char dv[128];
|
||||
memset(dv, 0, 128);
|
||||
snprintf(dv, 127, "%.2f,%.2f,%.2f,%.2f", airplay_volume, 0.0, 0.0, 0.0);
|
||||
if (volume_mode == vol_both) {
|
||||
// normalise the maximum output to the hardware device's max output
|
||||
snprintf(dv, 127, "%.2f,%.2f,%.2f,%.2f", airplay_volume,
|
||||
(scaled_attenuation - max_db + hw_max_db) / 100.0,
|
||||
(min_db - max_db + hw_max_db) / 100.0, (max_db - max_db + hw_max_db) / 100.0);
|
||||
} else {
|
||||
snprintf(dv, 127, "%.2f,%.2f,%.2f,%.2f", airplay_volume, scaled_attenuation / 100.0,
|
||||
min_db / 100.0, max_db / 100.0);
|
||||
}
|
||||
send_ssnc_metadata('pvol', dv, strlen(dv), 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (config.output->mute)
|
||||
config.output->mute(0);
|
||||
conn->software_mute_enabled = 0;
|
||||
|
||||
debug(2,
|
||||
"player_volume_without_notification: volume mode is %d, airplay volume is %f, "
|
||||
"software_attenuation: %f, hardware_attenuation: %f, muting "
|
||||
"is disabled.",
|
||||
volume_mode, airplay_volume, software_attenuation, hardware_attenuation);
|
||||
}
|
||||
/*
|
||||
}
|
||||
|
||||
#ifdef CONFIG_METADATA
|
||||
else {
|
||||
// here, send the 'pvol' metadata message when the airplay volume information
|
||||
// is being used by shairport sync to control the output volume
|
||||
char dv[128];
|
||||
memset(dv, 0, 128);
|
||||
snprintf(dv, 127, "%.2f,%.2f,%.2f,%.2f", airplay_volume, 0.0, 0.0, 0.0);
|
||||
send_ssnc_metadata('pvol', dv, strlen(dv), 1);
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
// here, store the volume for possible use in the future
|
||||
config.airplay_volume = airplay_volume;
|
||||
debug_mutex_unlock(&conn->volume_control_mutex, 3);
|
||||
|
||||
@@ -50,8 +50,8 @@
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "activity_monitor.h"
|
||||
#include "config.h"
|
||||
|
||||
#ifdef CONFIG_OPENSSL
|
||||
#include <openssl/md5.h>
|
||||
@@ -1560,10 +1560,9 @@ struct pairings {
|
||||
uint8_t public_key[32];
|
||||
|
||||
struct pairings *next;
|
||||
} *pairings;
|
||||
} * pairings;
|
||||
|
||||
static struct pairings * pairing_find(const char *device_id)
|
||||
{
|
||||
static struct pairings *pairing_find(const char *device_id) {
|
||||
for (struct pairings *pairing = pairings; pairing; pairing = pairing->next) {
|
||||
if (strcmp(device_id, pairing->device_id) == 0)
|
||||
return pairing;
|
||||
@@ -1595,7 +1594,8 @@ static void pairing_remove(struct pairings *pairing) {
|
||||
free(pairing);
|
||||
}
|
||||
|
||||
static int pairing_add_cb(uint8_t public_key[32], const char *device_id, void *cb_arg __attribute__((unused))) {
|
||||
static int pairing_add_cb(uint8_t public_key[32], const char *device_id,
|
||||
void *cb_arg __attribute__((unused))) {
|
||||
debug(1, "pair-add cb for %s", device_id);
|
||||
|
||||
struct pairings *pairing = pairing_find(device_id);
|
||||
@@ -1608,7 +1608,8 @@ static int pairing_add_cb(uint8_t public_key[32], const char *device_id, void *c
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pairing_remove_cb(uint8_t public_key[32] __attribute__((unused)), const char *device_id, void *cb_arg __attribute__((unused))) {
|
||||
static int pairing_remove_cb(uint8_t public_key[32] __attribute__((unused)), const char *device_id,
|
||||
void *cb_arg __attribute__((unused))) {
|
||||
debug(1, "pair-remove cb for %s", device_id);
|
||||
|
||||
struct pairings *pairing = pairing_find(device_id);
|
||||
@@ -1621,7 +1622,8 @@ static int pairing_remove_cb(uint8_t public_key[32] __attribute__((unused)), con
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pairing_list_cb(pair_cb enum_cb, void *enum_cb_arg, void *cb_arg __attribute__((unused))) {
|
||||
static void pairing_list_cb(pair_cb enum_cb, void *enum_cb_arg,
|
||||
void *cb_arg __attribute__((unused))) {
|
||||
debug(1, "pair-list cb");
|
||||
|
||||
for (struct pairings *pairing = pairings; pairing; pairing = pairing->next) {
|
||||
@@ -1629,10 +1631,12 @@ static void pairing_list_cb(pair_cb enum_cb, void *enum_cb_arg, void *cb_arg __a
|
||||
}
|
||||
}
|
||||
|
||||
void handle_pair_add(rtsp_conn_info *conn __attribute__((unused)), rtsp_message *req, rtsp_message *resp) {
|
||||
void handle_pair_add(rtsp_conn_info *conn __attribute__((unused)), rtsp_message *req,
|
||||
rtsp_message *resp) {
|
||||
uint8_t *body = NULL;
|
||||
size_t body_len = 0;
|
||||
int ret = pair_add(PAIR_SERVER_HOMEKIT, &body, &body_len, pairing_add_cb, NULL, (const uint8_t *)req->content, req->contentlength);
|
||||
int ret = pair_add(PAIR_SERVER_HOMEKIT, &body, &body_len, pairing_add_cb, NULL,
|
||||
(const uint8_t *)req->content, req->contentlength);
|
||||
if (ret < 0) {
|
||||
debug(1, "pair-add returned an error");
|
||||
resp->respcode = 451;
|
||||
@@ -1644,10 +1648,12 @@ void handle_pair_add(rtsp_conn_info *conn __attribute__((unused)), rtsp_message
|
||||
debug_log_rtsp_message(2, "pair-add response", resp);
|
||||
}
|
||||
|
||||
void handle_pair_list(rtsp_conn_info *conn __attribute__((unused)), rtsp_message *req, rtsp_message *resp) {
|
||||
void handle_pair_list(rtsp_conn_info *conn __attribute__((unused)), rtsp_message *req,
|
||||
rtsp_message *resp) {
|
||||
uint8_t *body = NULL;
|
||||
size_t body_len = 0;
|
||||
int ret = pair_list(PAIR_SERVER_HOMEKIT, &body, &body_len, pairing_list_cb, NULL, (const uint8_t *)req->content, req->contentlength);
|
||||
int ret = pair_list(PAIR_SERVER_HOMEKIT, &body, &body_len, pairing_list_cb, NULL,
|
||||
(const uint8_t *)req->content, req->contentlength);
|
||||
if (ret < 0) {
|
||||
debug(1, "pair-list returned an error");
|
||||
resp->respcode = 451;
|
||||
@@ -1659,10 +1665,12 @@ void handle_pair_list(rtsp_conn_info *conn __attribute__((unused)), rtsp_message
|
||||
debug_log_rtsp_message(2, "pair-list response", resp);
|
||||
}
|
||||
|
||||
void handle_pair_remove(rtsp_conn_info *conn __attribute__((unused)), rtsp_message *req, rtsp_message *resp) {
|
||||
void handle_pair_remove(rtsp_conn_info *conn __attribute__((unused)), rtsp_message *req,
|
||||
rtsp_message *resp) {
|
||||
uint8_t *body = NULL;
|
||||
size_t body_len = 0;
|
||||
int ret = pair_remove(PAIR_SERVER_HOMEKIT, &body, &body_len, pairing_remove_cb, NULL, (const uint8_t *)req->content, req->contentlength);
|
||||
int ret = pair_remove(PAIR_SERVER_HOMEKIT, &body, &body_len, pairing_remove_cb, NULL,
|
||||
(const uint8_t *)req->content, req->contentlength);
|
||||
if (ret < 0) {
|
||||
debug(1, "pair-remove returned an error");
|
||||
resp->respcode = 451;
|
||||
@@ -1867,20 +1875,21 @@ void handle_fp_setup(__attribute__((unused)) rtsp_conn_info *conn, rtsp_message
|
||||
}
|
||||
|
||||
/*
|
||||
<key>Identifier</key>
|
||||
<string>21cc689d-d5de-4814-872c-71d1426b57e0</string>
|
||||
<key>Enable_HK_Access_Control</key>
|
||||
<true/>
|
||||
<key>PublicKey</key>
|
||||
<data>
|
||||
qXJDhhL5F3OACL+HO7LVLQVdy0OJtavepjpF720PaOQ=
|
||||
</data>
|
||||
<key>Device_Name</key>
|
||||
<string>MyDevice</string>
|
||||
<key>Access_Control_Level</key>
|
||||
<integer>0</integer>
|
||||
<key>Identifier</key>
|
||||
<string>21cc689d-d5de-4814-872c-71d1426b57e0</string>
|
||||
<key>Enable_HK_Access_Control</key>
|
||||
<true/>
|
||||
<key>PublicKey</key>
|
||||
<data>
|
||||
qXJDhhL5F3OACL+HO7LVLQVdy0OJtavepjpF720PaOQ=
|
||||
</data>
|
||||
<key>Device_Name</key>
|
||||
<string>MyDevice</string>
|
||||
<key>Access_Control_Level</key>
|
||||
<integer>0</integer>
|
||||
*/
|
||||
void handle_configure(rtsp_conn_info *conn __attribute__((unused)), rtsp_message *req __attribute__((unused)), rtsp_message *resp) {
|
||||
void handle_configure(rtsp_conn_info *conn __attribute__((unused)),
|
||||
rtsp_message *req __attribute__((unused)), rtsp_message *resp) {
|
||||
uint8_t public_key[32];
|
||||
|
||||
pair_public_key_get(PAIR_SERVER_HOMEKIT, public_key, config.airplay_device_id);
|
||||
@@ -1889,7 +1898,8 @@ void handle_configure(rtsp_conn_info *conn __attribute__((unused)), rtsp_message
|
||||
|
||||
plist_dict_set_item(response_plist, "Identifier", plist_new_string(config.airplay_pi));
|
||||
plist_dict_set_item(response_plist, "Enable_HK_Access_Control", plist_new_bool(1));
|
||||
plist_dict_set_item(response_plist, "PublicKey", plist_new_data((const char *)public_key, sizeof(public_key)));
|
||||
plist_dict_set_item(response_plist, "PublicKey",
|
||||
plist_new_data((const char *)public_key, sizeof(public_key)));
|
||||
plist_dict_set_item(response_plist, "Device_Name", plist_new_string(config.service_name));
|
||||
plist_dict_set_item(response_plist, "Access_Control_Level", plist_new_uint(0));
|
||||
|
||||
@@ -2238,7 +2248,7 @@ void handle_setup_2(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp)
|
||||
|
||||
// hack.
|
||||
conn->max_frames_per_packet = 352; // number of audio frames per packet.
|
||||
conn->input_rate = 44100; // we are stuck with this for the moment.
|
||||
conn->input_rate = 44100; // we are stuck with this for the moment.
|
||||
conn->input_num_channels = 2;
|
||||
conn->input_bit_depth = 16;
|
||||
conn->input_bytes_per_frame = conn->input_num_channels * ((conn->input_bit_depth + 7) / 8);
|
||||
@@ -2254,7 +2264,6 @@ void handle_setup_2(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp)
|
||||
plist_dict_set_item(stream0dict, "audioBufferSize",
|
||||
plist_new_uint(conn->ap2_audio_buffer_size));
|
||||
|
||||
|
||||
// this should be cancelled by an activity_monitor_signify_activity(1)
|
||||
// call in the SETRATEANCHORI handler, which should come up right away
|
||||
activity_monitor_signify_activity(0);
|
||||
@@ -4414,7 +4423,7 @@ void *rtsp_listen_loop(__attribute((unused)) void *arg) {
|
||||
*p++ = ap1_featuresString;
|
||||
*p++ = firmware_version;
|
||||
*p++ = "md=2";
|
||||
*p++ = "am=SPS";
|
||||
*p++ = "am=Shairport Sync";
|
||||
*p++ = "sf=0x4";
|
||||
*p++ = "tp=UDP";
|
||||
*p++ = "vn=65537";
|
||||
@@ -4475,7 +4484,7 @@ void *rtsp_listen_loop(__attribute((unused)) void *arg) {
|
||||
*p++ = "acl=0";
|
||||
*p++ = "rsf=0x0";
|
||||
*p++ = firmware_version;
|
||||
*p++ = "model=SPS";
|
||||
*p++ = "model=Shairport Sync";
|
||||
char piString[64];
|
||||
snprintf(piString, sizeof(piString), "pi=%s", config.airplay_pi);
|
||||
*p++ = piString;
|
||||
|
||||
Reference in New Issue
Block a user