116 lines
2.5 KiB
C
116 lines
2.5 KiB
C
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include "sexyal.h"
|
||
|
#include "convert.h"
|
||
|
|
||
|
#ifdef WIN32
|
||
|
|
||
|
#else
|
||
|
#include "drivers/oss.h"
|
||
|
#endif
|
||
|
|
||
|
static uint32_t FtoB(const SexyAL_format *format, uint32_t frames)
|
||
|
{
|
||
|
return(frames*format->channels*(format->sampformat>>4));
|
||
|
}
|
||
|
/*
|
||
|
static uint32_t BtoF(const SexyAL_format *format, uint32_t bytes)
|
||
|
{
|
||
|
return(bytes / (format->channels * (format->sampformat>>4)));
|
||
|
}
|
||
|
*/
|
||
|
static uint32_t CanWrite(SexyAL_device *device)
|
||
|
{
|
||
|
uint32_t bytes,frames;
|
||
|
|
||
|
#ifdef WIN32
|
||
|
bytes=SexyALI_DSound_RawCanWrite(device);
|
||
|
#else
|
||
|
bytes=SexyALI_OSS_RawCanWrite(device);
|
||
|
#endif
|
||
|
frames=bytes / device->format.channels / (device->format.sampformat>>4);
|
||
|
|
||
|
return(frames);
|
||
|
}
|
||
|
|
||
|
static uint32_t Write(SexyAL_device *device, void *data, uint32_t frames)
|
||
|
{
|
||
|
uint8_t buffer[2048*4];
|
||
|
|
||
|
while(frames)
|
||
|
{
|
||
|
int32_t tmp;
|
||
|
|
||
|
tmp=frames;
|
||
|
if(tmp>2048)
|
||
|
{
|
||
|
tmp=2048;
|
||
|
frames-=2048;
|
||
|
}
|
||
|
else frames-=tmp;
|
||
|
|
||
|
SexiALI_Convert(&device->srcformat, &device->format, buffer, data, tmp);
|
||
|
//printf("%02x, %02x, %02x\n", device->srcformat.sampformat, device->srcformat.byteorder, device->srcformat.channels);
|
||
|
//printf("buffer: %d\n",buffer[0]);
|
||
|
/* FIXME: Return the actual number of frame written. It should always equal
|
||
|
the number of frames requested to be written, except in cases of sound device
|
||
|
failures.
|
||
|
*/
|
||
|
#ifdef WIN32
|
||
|
SexyALI_DSound_RawWrite(device,buffer,FtoB(&device->format,tmp));
|
||
|
#else
|
||
|
SexyALI_OSS_RawWrite(device,buffer,FtoB(&device->format,tmp));
|
||
|
#endif
|
||
|
}
|
||
|
return(frames);
|
||
|
}
|
||
|
|
||
|
static int Close(SexyAL_device *device)
|
||
|
{
|
||
|
#ifdef WIN32
|
||
|
return(SexyALI_DSound_Close(device));
|
||
|
#else
|
||
|
return(SexyALI_OSS_Close(device));
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
int SetConvert(struct __SexyAL_device *device, SexyAL_format *format)
|
||
|
{
|
||
|
memcpy(&device->srcformat,format,sizeof(SexyAL_format));
|
||
|
return(1);
|
||
|
}
|
||
|
|
||
|
static SexyAL_device *Open(SexyAL *iface, uint64_t id, SexyAL_format *format, SexyAL_buffering *buffering)
|
||
|
{
|
||
|
SexyAL_device *ret;
|
||
|
|
||
|
#ifdef WIN32
|
||
|
if(!(ret=SexyALI_DSound_Open(id,format,buffering))) return(0);
|
||
|
#else
|
||
|
if(!(ret=SexyALI_OSS_Open(id,format,buffering))) return(0);
|
||
|
#endif
|
||
|
|
||
|
ret->Write=Write;
|
||
|
ret->Close=Close;
|
||
|
ret->CanWrite=CanWrite;
|
||
|
ret->SetConvert=SetConvert;
|
||
|
return(ret);
|
||
|
}
|
||
|
|
||
|
void Destroy(SexyAL *iface)
|
||
|
{
|
||
|
free(iface);
|
||
|
}
|
||
|
|
||
|
void *SexyAL_Init(int version)
|
||
|
{
|
||
|
SexyAL *iface;
|
||
|
if(!version != 1) return(0);
|
||
|
|
||
|
iface=malloc(sizeof(SexyAL));
|
||
|
|
||
|
iface->Open=Open;
|
||
|
iface->Destroy=Destroy;
|
||
|
return((void *)iface);
|
||
|
}
|