mirror of
https://github.com/captain-amygdala/pistorm.git
synced 2026-01-28 12:39:10 +00:00
Adapt piaudio to work on PiStorm + A314 emulation
Maybe, maybe not, I have no idea. Untested, and will remain so, by me.
This commit is contained in:
17
a314/files_pi/.asoundrc
Normal file
17
a314/files_pi/.asoundrc
Normal file
@@ -0,0 +1,17 @@
|
||||
pcm.amiga {
|
||||
type plug
|
||||
slave {
|
||||
pcm {
|
||||
type file
|
||||
format raw
|
||||
file "/tmp/piaudio_pipe"
|
||||
slave.pcm null
|
||||
}
|
||||
format S8
|
||||
rate 18000
|
||||
channels 2
|
||||
}
|
||||
hint {
|
||||
description "Play audio to Amiga using A314"
|
||||
}
|
||||
}
|
||||
252
a314/files_pi/piaudio.py
Normal file
252
a314/files_pi/piaudio.py
Normal file
@@ -0,0 +1,252 @@
|
||||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2019 Niklas Ekström
|
||||
|
||||
import fcntl
|
||||
import logging
|
||||
import os
|
||||
import select
|
||||
import socket
|
||||
import struct
|
||||
import sys
|
||||
|
||||
fcntl.F_SETPIPE_SZ = 1031
|
||||
|
||||
logging.basicConfig(format = '%(levelname)s, %(asctime)s, %(name)s, line %(lineno)d: %(message)s')
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.setLevel(logging.INFO)
|
||||
|
||||
MSG_REGISTER_REQ = 1
|
||||
MSG_REGISTER_RES = 2
|
||||
MSG_DEREGISTER_REQ = 3
|
||||
MSG_DEREGISTER_RES = 4
|
||||
MSG_READ_MEM_REQ = 5
|
||||
MSG_READ_MEM_RES = 6
|
||||
MSG_WRITE_MEM_REQ = 7
|
||||
MSG_WRITE_MEM_RES = 8
|
||||
MSG_CONNECT = 9
|
||||
MSG_CONNECT_RESPONSE = 10
|
||||
MSG_DATA = 11
|
||||
MSG_EOS = 12
|
||||
MSG_RESET = 13
|
||||
|
||||
def wait_for_msg():
|
||||
header = b''
|
||||
while len(header) < 9:
|
||||
data = drv.recv(9 - len(header))
|
||||
if not data:
|
||||
logger.error('Connection to a314d was closed, terminating.')
|
||||
exit(-1)
|
||||
header += data
|
||||
(plen, stream_id, ptype) = struct.unpack('=IIB', header)
|
||||
payload = b''
|
||||
while len(payload) < plen:
|
||||
data = drv.recv(plen - len(payload))
|
||||
if not data:
|
||||
logger.error('Connection to a314d was closed, terminating.')
|
||||
exit(-1)
|
||||
payload += data
|
||||
return (stream_id, ptype, payload)
|
||||
|
||||
def send_register_req(name):
|
||||
m = struct.pack('=IIB', len(name), 0, MSG_REGISTER_REQ) + name
|
||||
drv.sendall(m)
|
||||
|
||||
def send_read_mem_req(address, length):
|
||||
m = struct.pack('=IIBII', 8, 0, MSG_READ_MEM_REQ, address, length)
|
||||
drv.sendall(m)
|
||||
|
||||
def read_mem(address, length):
|
||||
send_read_mem_req(address, length)
|
||||
stream_id, ptype, payload = wait_for_msg()
|
||||
if ptype != MSG_READ_MEM_RES:
|
||||
logger.error('Expected MSG_READ_MEM_RES but got %s. Shutting down.', ptype)
|
||||
exit(-1)
|
||||
return payload
|
||||
|
||||
def send_write_mem_req(address, data):
|
||||
m = struct.pack('=IIBI', 4 + len(data), 0, MSG_WRITE_MEM_REQ, address) + data
|
||||
drv.sendall(m)
|
||||
|
||||
def write_mem(address, data):
|
||||
send_write_mem_req(address, data)
|
||||
stream_id, ptype, payload = wait_for_msg()
|
||||
if ptype != MSG_WRITE_MEM_RES:
|
||||
logger.error('Expected MSG_WRITE_MEM_RES but got %s. Shutting down.', ptype)
|
||||
exit(-1)
|
||||
|
||||
def send_connect_response(stream_id, result):
|
||||
m = struct.pack('=IIBB', 1, stream_id, MSG_CONNECT_RESPONSE, result)
|
||||
drv.sendall(m)
|
||||
|
||||
def send_data(stream_id, data):
|
||||
m = struct.pack('=IIB', len(data), stream_id, MSG_DATA) + data
|
||||
drv.sendall(m)
|
||||
|
||||
def send_eos(stream_id):
|
||||
m = struct.pack('=IIB', 0, stream_id, MSG_EOS)
|
||||
drv.sendall(m)
|
||||
|
||||
def send_reset(stream_id):
|
||||
m = struct.pack('=IIB', 0, stream_id, MSG_RESET)
|
||||
drv.sendall(m)
|
||||
|
||||
current_stream_id = None
|
||||
first_msg = True
|
||||
raw_received = b''
|
||||
is_empty = [True, True]
|
||||
|
||||
def process_msg_data(payload):
|
||||
global ptrs, first_msg, raw_received
|
||||
|
||||
if first_msg:
|
||||
ptrs = struct.unpack('>II', payload)
|
||||
logger.debug('Received pointers %s', ptrs)
|
||||
first_msg = False
|
||||
return
|
||||
|
||||
buf_index = payload[0]
|
||||
|
||||
if len(raw_received) < 900*2:
|
||||
if not is_empty[buf_index]:
|
||||
data = b'\x00' * (900*2)
|
||||
send_write_mem_req(ptrs[buf_index], data)
|
||||
is_empty[buf_index] = True
|
||||
else:
|
||||
ldata = raw_received[0:900*2:2]
|
||||
rdata = raw_received[1:900*2:2]
|
||||
data = ldata + rdata
|
||||
raw_received = raw_received[900*2:]
|
||||
send_write_mem_req(ptrs[buf_index], data)
|
||||
is_empty[buf_index] = False
|
||||
|
||||
def process_drv_msg(stream_id, ptype, payload):
|
||||
global current_stream_id, first_msg
|
||||
|
||||
if ptype == MSG_CONNECT:
|
||||
if payload == b'piaudio' and current_stream_id is None:
|
||||
logger.info('Amiga connected')
|
||||
current_stream_id = stream_id
|
||||
first_msg = True
|
||||
send_connect_response(stream_id, 0)
|
||||
else:
|
||||
send_connect_response(stream_id, 3)
|
||||
elif current_stream_id == stream_id:
|
||||
if ptype == MSG_DATA:
|
||||
process_msg_data(payload)
|
||||
elif ptype == MSG_EOS:
|
||||
pass
|
||||
elif ptype == MSG_RESET:
|
||||
current_stream_id = None
|
||||
logger.info('Amiga disconnected')
|
||||
|
||||
done = False
|
||||
|
||||
try:
|
||||
idx = sys.argv.index('-ondemand')
|
||||
except ValueError:
|
||||
idx = -1
|
||||
|
||||
if idx != -1:
|
||||
fd = int(sys.argv[idx + 1])
|
||||
drv = socket.socket(fileno=fd)
|
||||
else:
|
||||
drv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
drv.connect(('localhost', 7110))
|
||||
drv.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
||||
|
||||
send_register_req(b'piaudio')
|
||||
_, _, payload = wait_for_msg()
|
||||
if payload[0] != 1:
|
||||
logger.error('Unable to register piaudio with driver, shutting down')
|
||||
drv.close()
|
||||
done = True
|
||||
|
||||
rbuf = b''
|
||||
|
||||
PIPE_NAME = '/tmp/piaudio_pipe'
|
||||
|
||||
if not done:
|
||||
exists = True
|
||||
try:
|
||||
if (os.stat(PIPE_NAME).st_mode & 0o170000) != 0o10000:
|
||||
logger.error('A file that is not a named pipe exists at ' + PIPE_NAME)
|
||||
done = True
|
||||
except:
|
||||
exists = False
|
||||
|
||||
if not done and not exists:
|
||||
try:
|
||||
os.mkfifo(PIPE_NAME)
|
||||
except:
|
||||
logger.error('Unable to create named pipe at ' + PIPE_NAME)
|
||||
done = True
|
||||
|
||||
if not done:
|
||||
try:
|
||||
pipe_fd = os.open(PIPE_NAME, os.O_RDONLY | os.O_NONBLOCK)
|
||||
fcntl.fcntl(pipe_fd, fcntl.F_SETPIPE_SZ, 4096)
|
||||
except:
|
||||
logger.error('Unable to open named pipe at ' + PIPE_NAME)
|
||||
done = True
|
||||
|
||||
if not done:
|
||||
logger.info('piaudio service is running')
|
||||
|
||||
while not done:
|
||||
sel_fds = [drv]
|
||||
|
||||
if idx == -1:
|
||||
sel_fds.append(sys.stdin)
|
||||
|
||||
if len(raw_received) < 900*2:
|
||||
sel_fds.append(pipe_fd)
|
||||
|
||||
rfd, wfd, xfd = select.select(sel_fds, [], [], 5.0)
|
||||
|
||||
for fd in rfd:
|
||||
if fd == sys.stdin:
|
||||
line = sys.stdin.readline()
|
||||
if not line or line.startswith('quit'):
|
||||
if current_stream_id is not None:
|
||||
send_reset(current_stream_id)
|
||||
drv.close()
|
||||
done = True
|
||||
elif fd == drv:
|
||||
buf = drv.recv(1024)
|
||||
if not buf:
|
||||
if current_stream_id is not None:
|
||||
send_reset(current_stream_id)
|
||||
drv.close()
|
||||
done = True
|
||||
else:
|
||||
rbuf += buf
|
||||
while True:
|
||||
if len(rbuf) < 9:
|
||||
break
|
||||
|
||||
(plen, stream_id, ptype) = struct.unpack('=IIB', rbuf[:9])
|
||||
if len(rbuf) < 9 + plen:
|
||||
break
|
||||
|
||||
rbuf = rbuf[9:]
|
||||
payload = rbuf[:plen]
|
||||
rbuf = rbuf[plen:]
|
||||
|
||||
process_drv_msg(stream_id, ptype, payload)
|
||||
elif fd == pipe_fd:
|
||||
data = os.read(pipe_fd, 900*2)
|
||||
|
||||
if len(data) == 0:
|
||||
os.close(pipe_fd)
|
||||
|
||||
l = len(raw_received)
|
||||
c = l // (900*2)
|
||||
if c * 900*2 < l:
|
||||
raw_received += b'\x00' * ((c + 1) * 900*2 - l)
|
||||
|
||||
pipe_fd = os.open(PIPE_NAME, os.O_RDONLY | os.O_NONBLOCK)
|
||||
fcntl.fcntl(pipe_fd, fcntl.F_SETPIPE_SZ, 4096)
|
||||
else:
|
||||
raw_received += data
|
||||
BIN
a314/software-amiga/piaudio
Normal file
BIN
a314/software-amiga/piaudio
Normal file
Binary file not shown.
13
a314/software-amiga/piaudio_pistorm/README.md
Normal file
13
a314/software-amiga/piaudio_pistorm/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# PiAudio
|
||||
|
||||
PiAudio is a service that integrates with ALSA, the sound sub-system on the Raspberry Pi, and lets sound samples be played via Paula on the Amiga.
|
||||
|
||||
The *piaudio* program should run on the Amiga. It allocates two sounds channels, one left and one right. Using the following command the piaudio program can run in the background:
|
||||
```
|
||||
run piaudio >NIL:
|
||||
```
|
||||
|
||||
The file *.asoundrc* should be stored in `/home/pi` on the RPi. Most programs that play audio on the RPi can then be used. One such program is mpg123, which is started as:
|
||||
```
|
||||
mpg123 -a amiga song.mp3
|
||||
```
|
||||
1
a314/software-amiga/piaudio_pistorm/build.bat
Normal file
1
a314/software-amiga/piaudio_pistorm/build.bat
Normal file
@@ -0,0 +1 @@
|
||||
vc piaudio.c -lamiga -o ../piaudio
|
||||
319
a314/software-amiga/piaudio_pistorm/piaudio.c
Normal file
319
a314/software-amiga/piaudio_pistorm/piaudio.c
Normal file
@@ -0,0 +1,319 @@
|
||||
#include <exec/types.h>
|
||||
#include <exec/memory.h>
|
||||
|
||||
#include <libraries/dos.h>
|
||||
|
||||
#include <devices/audio.h>
|
||||
|
||||
#include <proto/exec.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "../../a314device/a314.h"
|
||||
#include "../../a314device/proto_a314.h"
|
||||
|
||||
#include <clib/alib_protos.h>
|
||||
|
||||
#define SERVICE_NAME "piaudio"
|
||||
|
||||
#define FREQ 18000
|
||||
#define BUFFER_LEN_MS 50
|
||||
#define SAMPLES (FREQ * BUFFER_LEN_MS / 1000)
|
||||
|
||||
#define R0 1
|
||||
#define L0 2
|
||||
#define L1 4
|
||||
#define R1 8
|
||||
|
||||
#define LEFT_CHAN_MASK (L0 | L1)
|
||||
#define RIGHT_CHAN_MASK (R0 | R1)
|
||||
|
||||
#define LEFT 0
|
||||
#define RIGHT 1
|
||||
|
||||
struct MsgPort *sync_mp = NULL;
|
||||
struct MsgPort *async_mp = NULL;
|
||||
|
||||
struct A314_IORequest *sync_a314_req = NULL;
|
||||
struct A314_IORequest *write_a314_req = NULL;
|
||||
|
||||
struct Library *A314Base;
|
||||
|
||||
char *audio_buffers[4] = { NULL, NULL, NULL, NULL };
|
||||
|
||||
struct IOAudio *sync_audio_req = NULL;
|
||||
struct IOAudio *async_audio_req[4] = { NULL, NULL, NULL, NULL };
|
||||
|
||||
ULONG allocated_channels;
|
||||
|
||||
BOOL a314_device_open = FALSE;
|
||||
BOOL audio_device_open = FALSE;
|
||||
BOOL stream_open = FALSE;
|
||||
BOOL pending_a314_write = FALSE;
|
||||
|
||||
ULONG socket;
|
||||
int back_index = 0;
|
||||
char awbuf[8];
|
||||
|
||||
void start_a314_cmd(struct MsgPort *reply_port, struct A314_IORequest *ior, UWORD cmd, char *buffer, int length)
|
||||
{
|
||||
ior->a314_Request.io_Message.mn_ReplyPort = reply_port;
|
||||
ior->a314_Request.io_Command = cmd;
|
||||
ior->a314_Request.io_Error = 0;
|
||||
ior->a314_Socket = socket;
|
||||
ior->a314_Buffer = buffer;
|
||||
ior->a314_Length = length;
|
||||
SendIO((struct IORequest *)ior);
|
||||
}
|
||||
|
||||
BYTE a314_connect(char *name)
|
||||
{
|
||||
socket = time(NULL);
|
||||
start_a314_cmd(sync_mp, sync_a314_req, A314_CONNECT, name, strlen(name));
|
||||
Wait(1L << sync_mp->mp_SigBit);
|
||||
GetMsg(sync_mp);
|
||||
return sync_a314_req->a314_Request.io_Error;
|
||||
}
|
||||
|
||||
BYTE a314_write(char *buffer, int length)
|
||||
{
|
||||
start_a314_cmd(sync_mp, sync_a314_req, A314_WRITE, buffer, length);
|
||||
Wait(1L << sync_mp->mp_SigBit);
|
||||
GetMsg(sync_mp);
|
||||
return sync_a314_req->a314_Request.io_Error;
|
||||
}
|
||||
|
||||
BYTE a314_eos()
|
||||
{
|
||||
start_a314_cmd(sync_mp, sync_a314_req, A314_EOS, NULL, 0);
|
||||
Wait(1L << sync_mp->mp_SigBit);
|
||||
GetMsg(sync_mp);
|
||||
return sync_a314_req->a314_Request.io_Error;
|
||||
}
|
||||
|
||||
BYTE a314_reset()
|
||||
{
|
||||
start_a314_cmd(sync_mp, sync_a314_req, A314_RESET, NULL, 0);
|
||||
Wait(1L << sync_mp->mp_SigBit);
|
||||
GetMsg(sync_mp);
|
||||
return sync_a314_req->a314_Request.io_Error;
|
||||
}
|
||||
|
||||
void start_a314_write(char *buffer, int length)
|
||||
{
|
||||
start_a314_cmd(async_mp, write_a314_req, A314_WRITE, buffer, length);
|
||||
pending_a314_write = TRUE;
|
||||
}
|
||||
|
||||
void submit_async_audio_req(int index)
|
||||
{
|
||||
ULONG mask = ((index & 1) == LEFT) ? LEFT_CHAN_MASK : RIGHT_CHAN_MASK;
|
||||
ULONG unit = allocated_channels & mask;
|
||||
|
||||
async_audio_req[index]->ioa_Request.io_Message.mn_ReplyPort = async_mp;
|
||||
async_audio_req[index]->ioa_Request.io_Command = CMD_WRITE;
|
||||
async_audio_req[index]->ioa_Request.io_Flags = ADIOF_PERVOL;
|
||||
async_audio_req[index]->ioa_Request.io_Unit = (void*)unit;
|
||||
async_audio_req[index]->ioa_Data = audio_buffers[index];
|
||||
async_audio_req[index]->ioa_Length = SAMPLES;
|
||||
async_audio_req[index]->ioa_Period = 197;
|
||||
async_audio_req[index]->ioa_Volume = 64;
|
||||
async_audio_req[index]->ioa_Cycles = 1;
|
||||
BeginIO((struct IORequest *)async_audio_req[index]);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
SetTaskPri(FindTask(NULL), 50);
|
||||
|
||||
sync_mp = CreatePort(NULL, 0);
|
||||
if (!sync_mp)
|
||||
{
|
||||
printf("Unable to create sync reply message port\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
async_mp = CreatePort(NULL, 0);
|
||||
if (!async_mp)
|
||||
{
|
||||
printf("Unable to create async reply message port\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
sync_a314_req = (struct A314_IORequest *)CreateExtIO(sync_mp, sizeof(struct A314_IORequest));
|
||||
write_a314_req = (struct A314_IORequest *)CreateExtIO(sync_mp, sizeof(struct A314_IORequest));
|
||||
if (!sync_a314_req || !write_a314_req)
|
||||
{
|
||||
printf("Unable to create A314_IORequest\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (OpenDevice(A314_NAME, 0, (struct IORequest *)sync_a314_req, 0))
|
||||
{
|
||||
printf("Unable to open a314.device\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
a314_device_open = TRUE;
|
||||
|
||||
A314Base = &(sync_a314_req->a314_Request.io_Device->dd_Library);
|
||||
|
||||
memcpy(write_a314_req, sync_a314_req, sizeof(struct A314_IORequest));
|
||||
|
||||
audio_buffers[0] = AllocMem(SAMPLES * 2, MEMF_FAST | MEMF_CHIP | MEMF_CLEAR);
|
||||
audio_buffers[2] = AllocMem(SAMPLES * 2, MEMF_FAST | MEMF_CHIP | MEMF_CLEAR);
|
||||
if (!audio_buffers[0] || !audio_buffers[2])
|
||||
{
|
||||
printf("Unable to allocate audio buffers in A314 chip memory\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
audio_buffers[1] = audio_buffers[0] + SAMPLES;
|
||||
audio_buffers[3] = audio_buffers[2] + SAMPLES;
|
||||
|
||||
sync_audio_req = (struct IOAudio *)CreateExtIO(sync_mp, sizeof(struct IOAudio));
|
||||
if (!sync_audio_req)
|
||||
{
|
||||
printf("Unable to allocate sync audio request\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
async_audio_req[i] = AllocMem(sizeof(struct IOAudio), MEMF_PUBLIC);
|
||||
if (!async_audio_req[i])
|
||||
{
|
||||
printf("Unable to allocate async audio request\n");
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
UBYTE which_channels[] = { L0 | R0, L0 | R1, L1 | R0, L1 | R1 };
|
||||
|
||||
sync_audio_req->ioa_Request.io_Message.mn_ReplyPort = sync_mp;
|
||||
sync_audio_req->ioa_Request.io_Message.mn_Node.ln_Pri = 127;
|
||||
sync_audio_req->ioa_Request.io_Command = ADCMD_ALLOCATE;
|
||||
sync_audio_req->ioa_Request.io_Flags = ADIOF_NOWAIT;
|
||||
sync_audio_req->ioa_AllocKey = 0;
|
||||
sync_audio_req->ioa_Data = which_channels;
|
||||
sync_audio_req->ioa_Length = sizeof(which_channels);
|
||||
|
||||
if (OpenDevice(AUDIONAME, 0, (struct IORequest *)sync_audio_req, 0))
|
||||
{
|
||||
printf("Unable to open audio.device\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
audio_device_open = TRUE;
|
||||
|
||||
allocated_channels = (ULONG)sync_audio_req->ioa_Request.io_Unit;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
memcpy(async_audio_req[i], sync_audio_req, sizeof(struct IOAudio));
|
||||
|
||||
if (a314_connect(SERVICE_NAME) != A314_CONNECT_OK)
|
||||
{
|
||||
printf("Unable to connect to piaudio service\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
stream_open = TRUE;
|
||||
|
||||
ULONG *buf_ptrs = (ULONG *)awbuf;
|
||||
buf_ptrs[0] = TranslateAddressA314(audio_buffers[0]);
|
||||
buf_ptrs[1] = TranslateAddressA314(audio_buffers[2]);
|
||||
if (a314_write(awbuf, 8) != A314_WRITE_OK)
|
||||
{
|
||||
printf("Unable to write buffer pointers\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
printf("PiAudio started, allocated channels: L%d, R%d\n",
|
||||
(allocated_channels & LEFT_CHAN_MASK) == L0 ? 0 : 1,
|
||||
(allocated_channels & RIGHT_CHAN_MASK) == R0 ? 0 : 1);
|
||||
|
||||
sync_audio_req->ioa_Request.io_Command = CMD_STOP;
|
||||
DoIO((struct IORequest *)sync_audio_req);
|
||||
|
||||
submit_async_audio_req(back_index + LEFT);
|
||||
submit_async_audio_req(back_index + RIGHT);
|
||||
|
||||
sync_audio_req->ioa_Request.io_Command = CMD_START;
|
||||
DoIO((struct IORequest *)sync_audio_req);
|
||||
|
||||
int pending_audio_reqs = 2;
|
||||
|
||||
ULONG portsig = 1L << async_mp->mp_SigBit;
|
||||
|
||||
printf("Press ctrl-c to exit...\n");
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (pending_audio_reqs <= 2)
|
||||
{
|
||||
back_index ^= 2;
|
||||
|
||||
submit_async_audio_req(back_index + LEFT);
|
||||
submit_async_audio_req(back_index + RIGHT);
|
||||
|
||||
pending_audio_reqs += 2;
|
||||
|
||||
if (!pending_a314_write)
|
||||
{
|
||||
awbuf[0] = back_index == 0 ? 0 : 1;
|
||||
start_a314_write(awbuf, 1);
|
||||
}
|
||||
}
|
||||
|
||||
ULONG signal = Wait(SIGBREAKF_CTRL_C | portsig);
|
||||
|
||||
if (signal & SIGBREAKF_CTRL_C)
|
||||
break;
|
||||
else if (signal & portsig)
|
||||
{
|
||||
struct Message *msg;
|
||||
while (msg = GetMsg(async_mp))
|
||||
{
|
||||
if (msg == (struct Message *)write_a314_req)
|
||||
{
|
||||
if (write_a314_req->a314_Request.io_Error == A314_WRITE_OK)
|
||||
pending_a314_write = FALSE;
|
||||
else
|
||||
goto cleanup;
|
||||
}
|
||||
else
|
||||
pending_audio_reqs--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (stream_open)
|
||||
a314_reset();
|
||||
if (audio_device_open)
|
||||
CloseDevice((struct IORequest *)sync_audio_req);
|
||||
for (i = 3; i >= 0; i--)
|
||||
if (async_audio_req[i])
|
||||
FreeMem(async_audio_req[i], sizeof(struct IOAudio));
|
||||
if (sync_audio_req)
|
||||
DeleteExtIO((struct IORequest *)sync_audio_req);
|
||||
if (audio_buffers[2])
|
||||
FreeMem(audio_buffers[2], SAMPLES * 2);
|
||||
if (audio_buffers[0])
|
||||
FreeMem(audio_buffers[0], SAMPLES * 2);
|
||||
if (a314_device_open)
|
||||
CloseDevice((struct IORequest *)sync_a314_req);
|
||||
if (write_a314_req)
|
||||
DeleteExtIO((struct IORequest *)write_a314_req);
|
||||
if (sync_a314_req)
|
||||
DeleteExtIO((struct IORequest *)sync_a314_req);
|
||||
if (async_mp)
|
||||
DeletePort(async_mp);
|
||||
if (sync_mp)
|
||||
DeletePort(sync_mp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user