ref: ee0395513ea7be03d7dc8aae4c0b4bfbb59c0427
dir: /snd.c/
#include <u.h>
#include <libc.h>
#include <stdio.h>
#include <thread.h>
#include "quakedef.h"
enum{
Nbuf = 8
};
static int afd;
static int sndon;
static uint wpos;
static Channel *schan;
static QLock sndlock;
static void
sproc(void *)
{
int n, sz;
threadsetgrp(THsnd);
for(;;){
if(recv(schan, nil) < 0)
break;
sz = shm->samplebits/8 * shm->samples;
if((n = write(afd, shm->buffer, sz)) != sz)
break;
qlock(&sndlock);
wpos += n;
qunlock(&sndlock);
}
fprint(2, "sproc %d: %r\n", threadpid(threadid()));
}
qboolean
SNDDMA_Init(void)
{
int i;
sndon = 0;
if((afd = open("/dev/audio", OWRITE)) < 0){
fprint(2, "open: %r\n");
return 0;
}
shm = &sn;
shm->splitbuffer = 0;
if((i = COM_CheckParm("-sndbits")) != 0)
shm->samplebits = atoi(com_argv[i+1]);
if(shm->samplebits != 16 && shm->samplebits != 8)
shm->samplebits = 16;
if((i = COM_CheckParm("-sndspeed")) != 0)
shm->speed = atoi(com_argv[i+1]);
else
shm->speed = 44100;
shm->channels = 2;
if(COM_CheckParm("-sndmono") != 0)
shm->channels = 1;
shm->samples = 4096;
shm->submission_chunk = 1;
if((shm->buffer = mallocz(shm->samplebits/8 * shm->samples, 1)) == nil)
sysfatal("SNDDMA_Init:mallocz: %r\n");
shm->samplepos = 0;
sndon = 1;
wpos = 0;
if((schan = chancreate(sizeof(int), Nbuf)) == nil)
sysfatal("SNDDMA_Init:chancreate: %r");
if(proccreate(sproc, nil, 8192) < 0)
sysfatal("SNDDMA_Init:proccreate: %r");
return 1;
}
uint
SNDDMA_GetDMAPos(void)
{
if(!sndon)
return 0;
qlock(&sndlock);
shm->samplepos = wpos / (shm->samplebits/8);
qunlock(&sndlock);
return shm->samplepos;
}
void
SNDDMA_Shutdown(void)
{
if(!sndon)
return;
threadkillgrp(THsnd);
close(afd);
free(shm->buffer);
if(schan != nil){
chanfree(schan);
schan = nil;
}
sndon = 0;
}
void
SNDDMA_Submit(void)
{
if(nbsend(schan, nil) < 0){
fprint(2, "SNDDMA_Submit:nbsend: %r\n");
SNDDMA_Shutdown();
}
}