📄 recplay.c
字号:
/*
* recplay.c
*
* A simple recording and playback program for the Linux Sound Driver 2.0
* or later.
*
* Copyright by Hannu Savolainen 1993
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. 2.
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#ifndef __STDC__
/* #include <getopt.h> */
#endif /* __STDC__ */
#include <fcntl.h>
#ifdef __STDC__
#include <string.h>
#else /* __STDC__ */
#include <strings.h>
#endif /* __STDC__ */
#include <sys/soundcard.h>
#define DEFAULT_DSP_SPEED 8000
#define RECORD 0
#define PLAY 1
#define AUDIO "/dev/dsp"
#define MIXER "/dev/mixer"
int prof = APF_NORMAL;
int timelimit = 0, dsp_speed = DEFAULT_DSP_SPEED, dsp_stereo = 0;
int samplesize = 16;
int quiet_mode = 0;
int audio, abuf_size;
int direction, omode;
int blksize=0;
int fragsize=0;
int mixer = 0;
int loopback = 0;
int line=SOUND_MASK_MIC; //default input source is MICIN
char *audiobuf;
signed char c;
char audio_name[20] = AUDIO;
void recplay (char *name);
int main (int argc, char *argv[])
{
char *command;
int tmp;
command = argv[0];
if (strstr (argv[0], "srec"))
{
direction = RECORD;
// omode = O_RDONLY;
omode = O_RDWR;
}
else if (strstr (argv[0], "splay"))
{
direction = PLAY;
// omode = O_WRONLY;
omode = O_RDWR;
}
else
{
fprintf (stderr,
"Error: command should be named either srec or splay\n");
exit (1);
}
while ((c = getopt(argc, argv, "lpqs:St:b:d:B:f:L")) != -1)
{
switch (c)
{
case 'l':
printf("l");
loopback = 1;
break;
case 'S':
printf("S");
dsp_stereo = 1;
break;
case 'q':
printf("q");
quiet_mode = 1;
break;
case 's':
printf("s");
dsp_speed = atoi (optarg);
if (dsp_speed < 300)
dsp_speed *= 1000;
break;
case 't':
printf("t");
timelimit = atoi (optarg);
break;
case 'b':
printf("b");
samplesize = atoi (optarg);
break;
case 'B':
printf("B");
blksize = atoi (optarg);
break;
case 'd':
printf("d");
strncpy(audio_name, optarg, 20);
break;
case 'f':
printf("f");
fragsize = 0xffff0000 | atoi (optarg);
break;
case 'p':
printf("p");
prof = APF_CPUINTENS;
break;
case 'L':
printf("L");
line = SOUND_MASK_LINE;
break;
default:
fprintf (stderr,
"Usage: %s [-qSL] [-l] [-t secs] [-s Hz] [-b 8|12|16] [-d device] [filename]\n", command);
exit (-1);
}
}
audio = open(audio_name, omode, 0);
if (audio == -1)
{
perror (audio_name);
//describe_error();
exit (-1);
}
if (fragsize != 0)
if (ioctl(audio, SNDCTL_DSP_SETFRAGMENT, &fragsize)==-1)
{
perror("SETFRAGMENT");
exit(-1);
}
tmp = samplesize;
ioctl(audio, SNDCTL_DSP_SAMPLESIZE, &samplesize);
if (tmp != samplesize)
{
fprintf(stderr, "Unable to set the sample size\n");
exit(-1);
}
ioctl(audio, SNDCTL_DSP_PROFILE, &prof);
if (ioctl (audio, SNDCTL_DSP_STEREO, &dsp_stereo)==-1)
{
fprintf (stderr, "%s: Unable to set mono/stereo\n", command);
perror (audio_name);
exit (-1);
}
if (ioctl (audio, SNDCTL_DSP_SPEED, &dsp_speed) == -1)
{
fprintf (stderr, "%s: Unable to set audio speed\n", command);
perror (audio_name);
exit (-1);
}
if (!quiet_mode)
{
fprintf (stderr, "Speed %d Hz ", dsp_speed);
if (dsp_stereo)
fprintf (stderr, "(stereo)\n");
else
fprintf (stderr, "(mono)\n");
if (samplesize != 8)
fprintf(stderr, "%d bits per sample\n", samplesize);
}
if (blksize > 0)
abuf_size = blksize;
else
{
ioctl (audio, SNDCTL_DSP_GETBLKSIZE, &abuf_size);
if (abuf_size < 1)
{
perror ("GETBLKSIZE");
exit (-1);
}
}
if ((audiobuf = malloc (abuf_size)) == NULL)
{
fprintf (stderr, "Unable to allocate input/output buffer\n");
exit (-1);
}
if (optind > argc - 1)
recplay (NULL);
else
while (optind <= argc - 1)
{
recplay (argv[optind++]);
}
close (audio);
return 0;
}
void recplay (char *name)
{
int fd, l;
int count, c;
if (!timelimit)
count = 0x7fffffff;
else
{
count = timelimit * dsp_speed;
if (dsp_stereo)
count *= 2;
if (samplesize != 8)
count *= 2;
}
if (direction == PLAY)
{
if (!name)
{
fd = 0;
name = "stdin";
}
else
{
if ((fd = open (name, O_RDONLY, 0)) == -1)
{
perror (name);
exit (-1);
}
}
while (count)
{
c = count;
if (c > abuf_size)
c = abuf_size;
if ((l = read (fd, audiobuf, c))> 0)
{
if (write (audio, audiobuf, l) != l)
{
perror (audio_name);
exit (-1);
}
count -= l;
}
else
{
if (l == -1)
{
perror (name);
exit (-1);
}
count = 0; /* Stop */
}
} /* while (count) */
if (fd != 0)
close (fd);
}
else // direction == RECORD
{
if (!loopback)
{
if (!name)
{ fd = 1;
name = "stdout";
}
if ((fd = open (name, O_WRONLY | O_CREAT, 0666)) == -1)
{
perror (name);
exit (-1);
}
}
mixer = open(MIXER, O_RDONLY);
if (0 != ioctl (mixer, SOUND_MIXER_WRITE_RECSRC, &line))
{
perror("SOUND_MIXER_WRITE_RECSRC error!\n");
exit(-1);
}
if (loopback)
{
// ioctl test
unsigned int dma_counter;
printf("abuf_size = %d\n", abuf_size);
while(count)
{
c = count;
if (c > abuf_size)
c = abuf_size;
if ((l = read (audio, audiobuf, c)) > 0)
{
if (write (audio, audiobuf, l) != l)
{
perror (name);
exit (-1);
}
count -= l;
}
/* if (0 == ioctl(audio, SNDCTL_DSP_GETICOUNTER, &dma_counter))
{
printf("IN: DMA counter = %d\n", dma_counter);
}
if (0 == ioctl(audio, SNDCTL_DSP_GETOCOUNTER, &dma_counter))
{
printf("OUT: DMA counter = %d\n", dma_couer);
}
*/
if (l == -1)
{
perror (audio_name);
exit (-1);
}
}
}
else
{
while (count)
{
c = count;
if (c > abuf_size)
c = abuf_size;
if ((l = read (audio, audiobuf, c)) > 0)
{
if (write (fd, audiobuf, l) != l)
{
perror (name);
exit (-1);
}
count -= l;
}
if (l == -1)
{
perror (audio_name);
exit (-1);
}
} /* While count */
}
if (fd != 1)
close (fd);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -