Skip to content

Commit

Permalink
Changes to avoid samples cutoff
Browse files Browse the repository at this point in the history
  • Loading branch information
Cacodemon345 committed Dec 15, 2024
1 parent 8a35b69 commit aee747c
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 48 deletions.
104 changes: 56 additions & 48 deletions src/usb/usb_audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,53 +241,16 @@ typedef struct usb_device_audio
bool mute;

int alt_iface_enabled;
int buffer_retented;
bool transfer_detected;
} usb_device_audio;

int
usb_device_audio_handle_data(usb_device_c *device, USBPacket *p)
{
int ret = 0;
usb_device_audio* usb_audio = (usb_device_audio*)device;

// check that the length is <= the max packet size of the device
if (p->len > usb_device_get_mps(device, p->devep)) {
//BX_DEBUG(("EP%d transfer length (%d) is greater than Max Packet Size (%d).", p->devep, p->len, usb_device_get_mps(device, (p->devep))));
}

switch (p->pid)
{
case USB_TOKEN_OUT:
{
if (p->devep == 1 && usb_audio->alt_iface_enabled)
{
// Null packets must be accepted as well.
if (p->len > 0)
fifo8_push_all(&usb_audio->audio_buf, p->data, p->len);
ret = p->len;
}
else
{
goto fail;
}
}
break;
default:
fail:
device->stall = 1;
ret = USB_RET_STALL;
break;
}

return ret;
}

void
usb_device_audio_handle_reset(usb_device_c *device)
{
usb_device_audio* usb_audio = (usb_device_audio*) device->priv;

usb_audio->alt_iface_enabled = 0;
fifo8_reset(&usb_audio->audio_buf);
}

void
Expand All @@ -297,7 +260,7 @@ usb_device_audio_handle_iface_change(usb_device_c* device, int iface)

usb_audio->alt_iface_enabled = !!iface;
if (usb_audio->alt_iface_enabled == 0)
fifo8_drop(&usb_audio->audio_buf, fifo8_num_used(&usb_audio->audio_buf));
fifo8_reset(&usb_audio->audio_buf);
}

/*
Expand Down Expand Up @@ -443,24 +406,68 @@ usb_device_audio_handle_control(usb_device_c *device, int request, int value, in
return ret;
}

int
usb_device_audio_handle_data(usb_device_c *device, USBPacket *p)
{
int ret = 0;
usb_device_audio* usb_audio = (usb_device_audio*)device;

switch (p->pid)
{
case USB_TOKEN_OUT:
{
if (p->devep == 1 && usb_audio->alt_iface_enabled)
{
// Null packets must be accepted as well.
if (p->len > 0)
fifo8_push_all(&usb_audio->audio_buf, p->data, p->len);
ret = p->len;
if (p->len > 0)
usb_audio->transfer_detected = true;
}
else
{
goto fail;
}
}
break;
default:
fail:
device->stall = 1;
ret = USB_RET_STALL;
break;
}

return ret;
}

/* We need to maintain a constant stream of data to the audio backend. The OS isn't
obliged to send zero-length packets in isochronous transfers to signal end of audio buffers.
*/

static uint8_t zero[192];
static void
usb_audio_sof(void *priv)
{
usb_device_audio* usb_audio = (usb_device_audio*)priv;

if (!usb_audio->transfer_detected) {
fifo8_push_all(&usb_audio->audio_buf, zero, 192);
}

usb_audio->transfer_detected = false;
}

static void
usb_audio_get_buffer(int32_t *buffer, int len, void *priv)
{
usb_device_audio* usb_audio = (usb_device_audio*)priv;

if (usb_audio->alt_iface_enabled == 0)
return;

if (fifo8_num_used(&usb_audio->audio_buf) < (SOUNDBUFLEN * 2 * 2))
{
usb_audio->buffer_retented = 0;
return;
}

usb_audio->buffer_retented++;
if (usb_audio->buffer_retented < 2)
return;

fifo8_pop_buf(&usb_audio->audio_buf, (uint8_t*)usb_audio->buffer, sizeof (usb_audio->buffer));
if (usb_audio->mute)
return; // Utter silence.
Expand Down Expand Up @@ -506,6 +513,7 @@ usb_audio_device_create(const device_t *info)
usb_audio->device.connected = true;
usb_audio->device.iface_alt = 1;
usb_audio->device.alt_iface_max = 1;
usb_audio->device.sof_callback = usb_audio_sof;

usb_audio->device.handle_iface_change = usb_device_audio_handle_iface_change;
usb_audio->device.handle_control = usb_device_audio_handle_control;
Expand Down
4 changes: 4 additions & 0 deletions src/usb/usb_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ enum {
#define USB_DT_OTHER_SPEED_CONFIG 0x07
#define USB_DT_INTERFACE_POWER 0x08


typedef void (*usb_sof_timer)(void* priv);
typedef struct USBPacket USBPacket;

// packet events
Expand Down Expand Up @@ -261,6 +263,8 @@ struct usb_device_c {
void (*handle_iface_change)(usb_device_c* device, int iface);
/* Initializes the device. Returns true on success. */
bool (*init)(usb_device_c *init);
/* Called after each SOF from the host. */
usb_sof_timer sof_callback;

/* Opaque data. */
void* priv;
Expand Down
6 changes: 6 additions & 0 deletions src/usb/usb_ohci_bochs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1834,6 +1834,12 @@ void usb_ohci_timer(void* priv)
}

} // end run schedule

/* Iterate through all ports and invoke SOF callbacks if those exist. */
for (int i = 0; i < 2; i++) {
if (hub->usb_port[i].device != NULL && hub->usb_port[i].device->sof_callback)
hub->usb_port[i].device->sof_callback(hub->usb_port[i].device->priv);
}
}

void usb_ohci_set_port_device(bx_ohci_core_t *hub, int port, usb_device_c *dev)
Expand Down
6 changes: 6 additions & 0 deletions src/usb/usb_uhci_bochs.c
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,12 @@ usb_uhci_timer(void *priv)
if (hub->usb_command.schedule == 0)
hub->usb_status.host_halted = 1;

/* Iterate through all ports and invoke SOF callbacks if those exist. */
for (int i = 0; i < 2; i++) {
if (hub->usb_port[i].device != NULL && hub->usb_port[i].device->sof_callback)
hub->usb_port[i].device->sof_callback(hub->usb_port[i].device->priv);
}

// TODO ?:
// If in Global_Suspend mode and any of usb_port[i] bits 6,3, or 1 are set,
// we need to issue a Global_Resume (set the global resume bit).
Expand Down

0 comments on commit aee747c

Please sign in to comment.