mirror of
https://github.com/halleysfifthinc/AVCLAN-Mockingboard.git
synced 2026-08-07 01:13:18 +00:00
Shift Device/Action enums to avclan.h
This commit is contained in:
+73
-53
@@ -6,24 +6,27 @@
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#include "avclan_defs.h"
|
||||
#include "avclan.h"
|
||||
#include "cdchanger.hpp"
|
||||
#include "device.hpp"
|
||||
#include "frame.hpp"
|
||||
#include "mediacontrol.h"
|
||||
#include "statustimer.h"
|
||||
|
||||
namespace {
|
||||
using namespace avclan;
|
||||
|
||||
constexpr uint8_t cdloading_resp[] = {dev_CD_CHANGER,
|
||||
dev_STATUS,
|
||||
Loading_Status_Report,
|
||||
0x00,
|
||||
0x01,
|
||||
0x00,
|
||||
0x01,
|
||||
0x00,
|
||||
0x01,
|
||||
0x02};
|
||||
constexpr uint8_t cdloading_resp[] = {
|
||||
to_underlying(Device::CD_CHANGER),
|
||||
to_underlying(Device::STATUS),
|
||||
to_underlying(Action::Loading_Status_Report),
|
||||
0x00,
|
||||
0x01,
|
||||
0x00,
|
||||
0x01,
|
||||
0x00,
|
||||
0x01,
|
||||
0x02};
|
||||
|
||||
constexpr int WIRE_SIZE = 8; // cd state report size in bytes
|
||||
constexpr int TIME_SKIP = 15; // seconds
|
||||
@@ -56,20 +59,23 @@ void CDChanger::init() {
|
||||
|
||||
void CDChanger::handle(const Frame *in, Frame *out) {
|
||||
const uint8_t *data = &in->data[1];
|
||||
const auto from = static_cast<devices>(*data++);
|
||||
const auto from = static_cast<Device>(*data++);
|
||||
/* const auto to = */ data++;
|
||||
const auto action = *data++;
|
||||
const auto action = static_cast<Action>(*data++);
|
||||
|
||||
static const uint8_t function_change_resp[] = {0x00, dev_CD_CHANGER, from,
|
||||
0xFF, 0x01};
|
||||
static const uint8_t function_change_resp[] = {
|
||||
0x00, to_underlying(Device::CD_CHANGER), to_underlying(from), 0xFF, 0x01};
|
||||
|
||||
using enum Action;
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wswitch-enum"
|
||||
// Unicast to CD changer: bytes are (0x00, from, to, action, [extra...]).
|
||||
switch (action) {
|
||||
case Enable_Function_Req:
|
||||
out->is_unicast = true;
|
||||
out->length = sizeof(function_change_resp);
|
||||
memcpy(out->data, function_change_resp, sizeof(function_change_resp));
|
||||
out->data[3] = Enable_Function_Resp;
|
||||
out->data[3] = to_underlying(Enable_Function_Resp);
|
||||
state = 0;
|
||||
flags2 = 0x80;
|
||||
out->reaction = r_StatusReport;
|
||||
@@ -80,7 +86,7 @@ void CDChanger::handle(const Frame *in, Frame *out) {
|
||||
stopPlaying();
|
||||
out->length = sizeof(function_change_resp);
|
||||
memcpy(out->data, function_change_resp, sizeof(function_change_resp));
|
||||
out->data[3] = Disable_Function_Resp;
|
||||
out->data[3] = to_underlying(Disable_Function_Resp);
|
||||
state = 0;
|
||||
flags2 = 0x80;
|
||||
out->is_unicast = true;
|
||||
@@ -90,8 +96,9 @@ void CDChanger::handle(const Frame *in, Frame *out) {
|
||||
case Eject: {
|
||||
// "Eject" label is multiply wrong; proper meaning unclear:
|
||||
// - First observed on initial multiple presses of "CD" button,
|
||||
// triggering (after {0x00, dev_CD_CHANGER, dev_COMM_v1, Insertion,
|
||||
// 0x01} response) proper activation of mockingboard/cd-changer.
|
||||
// triggering (after {0x00, Device::CD_CHANGER, Device::COMM_v1,
|
||||
// Insertion, 0x01} response) proper activation of
|
||||
// mockingboard/cd-changer.
|
||||
// - Subsequently observed when pressing (technically
|
||||
// releasing?) the fast-forward button and rewind
|
||||
if (static_cast<bool>(state & SEEKING)) { // FF/RW button released
|
||||
@@ -99,8 +106,9 @@ void CDChanger::handle(const Frame *in, Frame *out) {
|
||||
} else {
|
||||
out->is_unicast = true;
|
||||
{
|
||||
const uint8_t msg[] = {0x00, dev_CD_CHANGER, dev_CMD_SW, Insertion,
|
||||
0x01};
|
||||
const uint8_t msg[] = {0x00, to_underlying(Device::CD_CHANGER),
|
||||
to_underlying(Device::CMD_SW),
|
||||
to_underlying(Insertion), 0x01};
|
||||
out->length = sizeof(msg);
|
||||
memcpy(out->data, msg, sizeof(msg));
|
||||
}
|
||||
@@ -112,8 +120,15 @@ void CDChanger::handle(const Frame *in, Frame *out) {
|
||||
out->is_unicast = true;
|
||||
// No knowledge/understanding of field meaning/interpretation
|
||||
const uint8_t cdinitreport_resp[] = {
|
||||
0x00, dev_CD_CHANGER, from, Initial_Report_Response, 0x01, 0x31,
|
||||
0x10, 0x01, 0x01};
|
||||
0x00,
|
||||
to_underlying(Device::CD_CHANGER),
|
||||
to_underlying(from),
|
||||
to_underlying(Initial_Report_Response),
|
||||
0x01,
|
||||
0x31,
|
||||
0x10,
|
||||
0x01,
|
||||
0x01};
|
||||
out->length = sizeof(cdinitreport_resp);
|
||||
memcpy(out->data, cdinitreport_resp, sizeof(cdinitreport_resp));
|
||||
out->reaction = r_SendOnly;
|
||||
@@ -121,9 +136,9 @@ void CDChanger::handle(const Frame *in, Frame *out) {
|
||||
}
|
||||
case Playback_Request:
|
||||
out->data[0] = 0x00;
|
||||
out->data[1] = dev_CD_CHANGER;
|
||||
out->data[2] = from;
|
||||
out->data[3] = Playback_Report;
|
||||
out->data[1] = to_underlying(Device::CD_CHANGER);
|
||||
out->data[2] = to_underlying(from);
|
||||
out->data[3] = to_underlying(Playback_Report);
|
||||
out->length = WIRE_SIZE + 4;
|
||||
serialize(&out->data[4]);
|
||||
out->is_unicast = true;
|
||||
@@ -133,8 +148,8 @@ void CDChanger::handle(const Frame *in, Frame *out) {
|
||||
out->data[0] = 0x00;
|
||||
out->length = sizeof(cdloading_resp) + 1;
|
||||
memcpy(&out->data[1], cdloading_resp, sizeof(cdloading_resp));
|
||||
out->data[2] = from;
|
||||
out->data[3] = Loading_Response2;
|
||||
out->data[2] = to_underlying(from);
|
||||
out->data[3] = to_underlying(Loading_Response2);
|
||||
out->is_unicast = true;
|
||||
out->reaction = r_SendOnly;
|
||||
break;
|
||||
@@ -147,7 +162,7 @@ void CDChanger::handle(const Frame *in, Frame *out) {
|
||||
mins = 0xff;
|
||||
secs = 0x7f;
|
||||
flags2 = 0xc0;
|
||||
generateStatus(out, true, dev_CMD_SW);
|
||||
generateStatus(out, true, Device::CMD_SW);
|
||||
AVCLAN_mediaFunction(MEDIA_SKIP_FORWARD);
|
||||
out->reaction = r_TrackChange;
|
||||
break;
|
||||
@@ -163,7 +178,7 @@ void CDChanger::handle(const Frame *in, Frame *out) {
|
||||
mins = 0xff;
|
||||
secs = 0x7f;
|
||||
flags2 = 0xc0;
|
||||
generateStatus(out, true, dev_CMD_SW);
|
||||
generateStatus(out, true, Device::CMD_SW);
|
||||
AVCLAN_mediaFunction(MEDIA_SKIP_BACKWARD);
|
||||
out->reaction = r_TrackChange;
|
||||
break;
|
||||
@@ -174,7 +189,7 @@ void CDChanger::handle(const Frame *in, Frame *out) {
|
||||
secs -= 60;
|
||||
++mins;
|
||||
}
|
||||
generateStatus(out, true, dev_CMD_SW);
|
||||
generateStatus(out, true, Device::CMD_SW);
|
||||
AVCLAN_mediaFunction(MEDIA_SKIP_FORWARD);
|
||||
statustimer_reset(); // Skipped to a whole/round sec; ensure next tick
|
||||
// is ~1 sec from now
|
||||
@@ -194,7 +209,7 @@ void CDChanger::handle(const Frame *in, Frame *out) {
|
||||
}
|
||||
} else
|
||||
secs -= TIME_SKIP;
|
||||
generateStatus(out, true, dev_CMD_SW);
|
||||
generateStatus(out, true, Device::CMD_SW);
|
||||
AVCLAN_mediaFunction(MEDIA_SKIP_BACKWARD);
|
||||
statustimer_reset(); // Skipped to a whole/round sec; ensure next tick
|
||||
// is ~1 sec from now
|
||||
@@ -203,46 +218,47 @@ void CDChanger::handle(const Frame *in, Frame *out) {
|
||||
}
|
||||
case CD_Enable_Random:
|
||||
flags |= RANDOM;
|
||||
generateStatus(out, true, dev_CMD_SW);
|
||||
generateStatus(out, true, Device::CMD_SW);
|
||||
out->reaction = r_StatusReport;
|
||||
break;
|
||||
case CD_Disable_Random:
|
||||
flags &= ~RANDOM;
|
||||
generateStatus(out, true, dev_CMD_SW);
|
||||
generateStatus(out, true, Device::CMD_SW);
|
||||
out->reaction = r_StatusReport;
|
||||
break;
|
||||
case CD_Enable_Repeat:
|
||||
flags |= REPEAT;
|
||||
generateStatus(out, true, dev_CMD_SW);
|
||||
generateStatus(out, true, Device::CMD_SW);
|
||||
out->reaction = r_StatusReport;
|
||||
break;
|
||||
case CD_Disable_Repeat:
|
||||
flags &= ~REPEAT;
|
||||
generateStatus(out, true, dev_CMD_SW);
|
||||
generateStatus(out, true, Device::CMD_SW);
|
||||
out->reaction = r_StatusReport;
|
||||
break;
|
||||
case CD_Enable_Disk_Random:
|
||||
flags |= DISK_RANDOM;
|
||||
generateStatus(out, true, dev_CMD_SW);
|
||||
generateStatus(out, true, Device::CMD_SW);
|
||||
out->reaction = r_StatusReport;
|
||||
break;
|
||||
case CD_Disable_Disk_Random:
|
||||
flags &= ~DISK_RANDOM;
|
||||
generateStatus(out, true, dev_CMD_SW);
|
||||
generateStatus(out, true, Device::CMD_SW);
|
||||
out->reaction = r_StatusReport;
|
||||
break;
|
||||
case CD_Enable_Disk_Repeat:
|
||||
flags |= DISK_REPEAT;
|
||||
generateStatus(out, true, dev_CMD_SW);
|
||||
generateStatus(out, true, Device::CMD_SW);
|
||||
out->reaction = r_StatusReport;
|
||||
break;
|
||||
case CD_Disable_Disk_Repeat:
|
||||
flags &= ~DISK_REPEAT;
|
||||
generateStatus(out, true, dev_CMD_SW);
|
||||
generateStatus(out, true, Device::CMD_SW);
|
||||
out->reaction = r_StatusReport;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
}
|
||||
|
||||
void CDChanger::react(Frame *out, detail::Error::Send err) {
|
||||
@@ -258,8 +274,12 @@ void CDChanger::react(Frame *out, detail::Error::Send err) {
|
||||
}
|
||||
break;
|
||||
case r_Ejection: {
|
||||
const uint8_t play[] = {0x00, dev_COMM_CTRL, dev_COMM_v1,
|
||||
Insertion, dev_CD_CHANGER, 0x01};
|
||||
const uint8_t play[] = {0x00,
|
||||
to_underlying(Device::COMM_CTRL),
|
||||
to_underlying(Device::COMM_v1),
|
||||
to_underlying(Action::Insertion),
|
||||
to_underlying(Device::CD_CHANGER),
|
||||
0x01};
|
||||
out->length = sizeof(play);
|
||||
memcpy(out->data, play, sizeof(play));
|
||||
}
|
||||
@@ -270,8 +290,8 @@ void CDChanger::react(Frame *out, detail::Error::Send err) {
|
||||
out->peripheral_addr = 0x1FF;
|
||||
out->length = sizeof(cdloading_resp) + 1;
|
||||
memcpy(out->data, cdloading_resp, sizeof(cdloading_resp));
|
||||
out->data[1] = dev_STATUS;
|
||||
out->data[2] = Loading_Status_Report;
|
||||
out->data[1] = to_underlying(Device::STATUS);
|
||||
out->data[2] = to_underlying(Action::Loading_Status_Report);
|
||||
out->reaction = r_SendOnly;
|
||||
break;
|
||||
case r_TrackChange:
|
||||
@@ -281,12 +301,12 @@ void CDChanger::react(Frame *out, detail::Error::Send err) {
|
||||
[[fallthrough]];
|
||||
case r_NormalizeState:
|
||||
normalizeState();
|
||||
generateStatus(out, true, dev_STATUS);
|
||||
generateStatus(out, true, Device::STATUS);
|
||||
out->reaction = r_SendOnly;
|
||||
break;
|
||||
case r_StartPlaying:
|
||||
normalizeState();
|
||||
generateStatus(out, true, dev_STATUS);
|
||||
generateStatus(out, true, Device::STATUS);
|
||||
out->reaction = r_BeganPlaying;
|
||||
break;
|
||||
case r_BeganPlaying:
|
||||
@@ -294,7 +314,7 @@ void CDChanger::react(Frame *out, detail::Error::Send err) {
|
||||
out->reaction = r_Nothing;
|
||||
break;
|
||||
case r_StatusReport:
|
||||
generateStatus(out, true, dev_STATUS);
|
||||
generateStatus(out, true, Device::STATUS);
|
||||
out->reaction = r_SendOnly;
|
||||
break;
|
||||
case r_SendOnly: [[fallthrough]];
|
||||
@@ -311,7 +331,7 @@ void CDChanger::enable(Frame *out) {
|
||||
secs = 0;
|
||||
state = SEEKING | SEEKING_TRACK;
|
||||
flags2 = 0xc0;
|
||||
generateStatus(out, true, dev_STATUS);
|
||||
generateStatus(out, true, Device::STATUS);
|
||||
out->reaction = r_StartPlaying;
|
||||
}
|
||||
}
|
||||
@@ -321,7 +341,7 @@ void CDChanger::resolvepending() { statustimer_clearTick(); }
|
||||
|
||||
void CDChanger::emit(Frame *out, uint16_t peripheral) {
|
||||
out->peripheral_addr = peripheral;
|
||||
generateStatus(out, true, dev_STATUS);
|
||||
generateStatus(out, true, Device::STATUS);
|
||||
out->reaction = r_StateReport;
|
||||
}
|
||||
|
||||
@@ -379,7 +399,7 @@ void CDChanger::incrementTime() {
|
||||
|
||||
// Used for changed status messages
|
||||
void CDChanger::generateStatus(Frame *status, bool is_unicast,
|
||||
devices to) const {
|
||||
Device to) const {
|
||||
status->is_unicast = is_unicast;
|
||||
if (!is_unicast)
|
||||
status->peripheral_addr = 0x1FF;
|
||||
@@ -389,9 +409,9 @@ void CDChanger::generateStatus(Frame *status, bool is_unicast,
|
||||
uint8_t *data = status->data;
|
||||
if (is_unicast)
|
||||
*data++ = 0x00;
|
||||
*data++ = dev_CD_CHANGER;
|
||||
*data++ = to;
|
||||
*data++ = Status_Report;
|
||||
*data++ = to_underlying(Device::CD_CHANGER);
|
||||
*data++ = to_underlying(to);
|
||||
*data++ = to_underlying(Action::Status_Report);
|
||||
serialize(data);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user