⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 recplay.c

📁 Linux 下C语言播放器程序
💻 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 + -