1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
/*
kwintv, Video4Linux compatible KDE application
Copyright (C) 1998 Moritz Wenk (wenk@mathematik.uni-kl.de)
*/
#ifdef HAVE_CONFIG_H
#include <config.h> // config.h by configure
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/soundcard.h>
#include <sys/ioctl.h>
#include "dsp.h"
static char DSPerror[256];
#define DSP_PERROR(action,file) \
{sprintf(DSPerror,"%s: %s: %s\n",action,file,strerror(errno));fprintf(stderr,DSPerror);}
#define TRAP(txt) fprintf(stderr,"%s:%d:%s\n",__FILE__,__LINE__,txt);exit(1);
dsp::dsp( const char * dev )
{
if (-1 == (fd = ::open(dev, O_RDONLY))) {
DSP_PERROR("open",dev);
}
}
dsp::~dsp()
{
::close(fd);
if (buffer) close();
}
int dsp::open (int bits, int channels, int rate)
{
int afmt,trigger;
ioctl(fd, SNDCTL_DSP_RESET, 0);
int frag;
frag=(8<<16)|(10);//8 buffers, 1024 bytes each
ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &frag);
/* format */
switch (bits) {
case 16:
afmt = AFMT_S16_LE;
ioctl(fd, SNDCTL_DSP_SETFMT, &afmt);
if (afmt == AFMT_S16_LE)
break;
/* fall back*/
fprintf(stderr,"no 16 bit sound, trying 8 bit...\n");
bits = 8;
case 8:
afmt = AFMT_U8;
ioctl(fd, SNDCTL_DSP_SETFMT, &afmt);
if (afmt != AFMT_U8) {
fprintf(stderr,"Oops: no 8 bit sound ?\n");
goto err;
}
break;
default:
fprintf(stderr,"%d bit sound not supported\n",
bits);
goto err;
}
/* channels */
ioctl(fd, SNDCTL_DSP_CHANNELS, &channels);
/* sample rate */
ioctl(fd, SNDCTL_DSP_SPEED, &rate);
if (-1 == ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &blocksize))
goto err;
printf("%d\n",blocksize);
blocksize*=4;
buffer = (char *)malloc(blocksize);
/* trigger record */
trigger = ~PCM_ENABLE_INPUT;
ioctl(fd,SNDCTL_DSP_SETTRIGGER,&trigger);
trigger = PCM_ENABLE_INPUT;
ioctl(fd,SNDCTL_DSP_SETTRIGGER,&trigger);
return fd;
err:
return 0;
}
int dsp::close()
{
free(buffer);
buffer=0;
return 0;
}
char * dsp::readBuf()
{
if (blocksize != read(fd,buffer,blocksize)) {
//perror("read /dev/dsp");
return buffer;
// exit(1);
}
return buffer;
}
int dsp::getSize()
{
struct audio_buf_info z;
ioctl(fd, SNDCTL_DSP_GETISPACE, &z);
return z.bytes;
}
|