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

📄 test2.c

📁 这是一个自己开发的键盘驱动代码
💻 C
字号:

#include "test2.h"

/****************************************************************************/

/*
 *	Get stream size (just file size).
 */

static int getstreamsize(void)
{
	struct stat	st;
	if (stat(mp3_filename, &st) < 0)
		return(0);
	return(st.st_size);
}

/****************************************************************************/

/****************************************************************************/

/*
 *	Get another chunk of data into RAM.
 */

static UINT32 getnextbuffer()
{
	int	rc;

	printf("%s mp3_buffer_next_block:%p\n", __FUNCTION__, mp3_buffer_next_block);
	lseek(mp3_fd, mp3_buffer_next_block, SEEK_SET);
	rc = read(mp3_fd, mp3_buffer, MP3_BUF_SIZE);
	mp3_buffer_size = (rc < 0) ? 0 : rc;
	mp3_buffer_next_block += mp3_buffer_size;
	return(mp3_buffer_size);
}

/****************************************************************************/

/*
 *	Start our own bitstream access routines.
 */

INT32 bs_open(char *stream_name, INT32 buffer_size, INT32 *stream_size)
{
#if 0
	printf("bs_open: '%s'\n", stream_name);
#endif

	if (!mp3_buffer)
		return(0);

	mp3_buffer_offset = 0;

	/* We know total size, we can set it */
	*stream_size = mp3_stream_size;

	/* Just return a dummy handle (not NULL) */
	return(1);
}

/****************************************************************************/

void bs_close(INT32 handle)
{
#if 0
	printf("bs_close\n");
#endif
	/* Don't need to do anything... */
}

/****************************************************************************/

INT32 bs_read(INT32 handle, void *buffer, INT32 num_bytes)
{
	INT32 read_size;

//	printf("bs_read\n");
	
	if (!handle )
		return(-1);

tryagain:
	read_size = mp3_buffer_size - mp3_buffer_offset;
	if (read_size > num_bytes)
		read_size = num_bytes;

	if (read_size > 0) {
		if(!buffer)
			return(-1);
		memcpy(buffer, &mp3_buffer[mp3_buffer_offset], read_size);
		mp3_buffer_offset += read_size;
	} else {
		if (getnextbuffer() > 0) {
			mp3_buffer_offset = 0;
			goto tryagain;
		}
		read_size = -1; /* End of stream */
	}

	return(read_size);
}

/****************************************************************************/

int bs_seek(INT32 handle, INT32 abs_byte_seek_pos)
{
//	printf("bs_seek\n");
	
	if (!handle)
		return(-1);

	if (abs_byte_seek_pos <= 0)
		mp3_buffer_offset = 0;
	else if (abs_byte_seek_pos >= mp3_buffer_size)
		return(-1);
	else
		mp3_buffer_offset = abs_byte_seek_pos;
	return(0);
}


MPEGDEC_ACCESS bs_access = { bs_open, bs_close, bs_read, bs_seek };

/****************************************************************************/

/*
 *	Configure DSP engine settings for playing this track.
 */

void setdsp(int fd, int playstereo, int playbits)
{
	if (ioctl(fd, SNDCTL_DSP_SPEED, &mps->dec_frequency) < 0) {
		fprintf(stderr, "ERROR: Unable to set frequency to %d, "
				"errno=%d\n", mps->dec_frequency, errno);
		exit(1);
	}

	/* Check if data stream is stereo, otherwise must play mono. */
	stereo = (mps->channels == 1) ? 0 : playstereo;
	if (ioctl(fd, SNDCTL_DSP_STEREO, &stereo) < 0) {
		fprintf(stderr, "ERROR: Unable to set stereo to %d, "
				"errno=%d\n", stereo, errno);
		exit(1);
	}
	//ioctl(fd, SNDCTL_DSP_CHANNELS, &(mps->channels));

#if __BYTE_ORDER == __LITTLE_ENDIAN
	bits = (playbits == 16) ? AFMT_S16_LE : AFMT_U8;
#elif __BYTE_ORDER == __BIG_ENDIAN
	bits = (playbits == 16) ? AFMT_S16_BE : AFMT_U8;
#else
#error "I don't know what endian your machine is??"
#endif
	if (ioctl(fd, SNDCTL_DSP_SAMPLESIZE, &bits) < 0) {
		fprintf(stderr, "ERROR: Unable to set sample size to "
				"%d, errno=%d\n", bits, errno);
		exit(1);
	}
}

/****************************************************************************/

/*
 *	Write out the PCM data to the file descriptor, translating to
 *	the specified data format.
 */

int writepcm(int fd, INT16 *pcm[2], int count)
{
	unsigned short	*pcm0, *pcm1;
	unsigned char	*pbufbp;
	unsigned short	*pbufwp;
	char		*buf;
	int		i;

	if (count <= 0)
		return(count);

	buf = rawbuf;

	if (stereo) {
		if (bits == 8) {
			/* 8bit stereo */
			pcm0 = pcm[0];
			pcm1 = pcm[1];
			pbufbp = (unsigned char *) buf;
			for (i = 0; (i < count); i++) {
				*pbufbp++ = (*pcm0++ ^ 0x8000) >> 8;
				*pbufbp++ = (*pcm1++ ^ 0x8000) >> 8;
			}
			i = count * 2 * sizeof(unsigned char);
		} else {
			/* 16bit stereo */
			pcm0 = pcm[0];
			pcm1 = pcm[1];
			pbufwp = (unsigned short *) buf;
			for (i = 0; (i < count); i++) {
				*pbufwp++ = *pcm0++;
				*pbufwp++ = *pcm1++;
			}
			i = count * 2 * sizeof(unsigned short);
		}
	} else {
		if (bits == 8) {
			/* 8bit mono */
			pcm0 = pcm[0];
			pbufbp = (unsigned char *) buf;
			for (i = 0; (i < count); i++)
				*pbufbp++ = (*pcm0++ ^ 0x8000) >> 8;
			i = count * sizeof(unsigned char);
		} else {
			/* 16bit mono, no translation required! */
			i = count * sizeof(unsigned short);
			buf = (char *) pcm[0];
		}
	}

	if (prebufnow) {
		memcpy(&prebuffer[prebufcnt], buf, i);
		prebufcnt += i;
		if (prebufcnt > prebufnow) {
			write(fd, &prebuffer[0], prebufcnt);
			prebufnow = prebufcnt = 0;
		}
	} else {
		write(fd, buf, i);
	}

	return(i);
}

/****************************************************************************/

/*
 *	Flush out any remaining buffered PCM data. This is really to allow
 *	for prebuffing of files smaller than the prebuffer.
 */

void flushpcm(int fd)
{
	if (prebufnow) {
		write(fd, &prebuffer[0], prebufcnt);
		prebufnow = prebufcnt = 0;
	}
}

void close_all()
{
	close(mp3_fd);
	MPEGDEC_close(mps);
	mps = NULL;
	close(dspfd);
	ready = 0;
}

/****************************************************************************/

int ready_play( const char *fn )
//int main(int argc, char *argv[])
{
	int playbits, playstereo;
	char		*device;
	int		c, i, j;
	
	playstereo = 1;
	playbits = 16;
	quality = 2;
	prebuflimit = 64000;
	device = "/dev/dsp";
	
	mp3_buffer = (INT8 *) fmalloc(MP3_BUF_SIZE);
	if (!mp3_buffer) {
		fprintf(stderr, "ERROR: Can't allocate MPEG buffer\n");
		exit(0);
	}

	for (i = 0; (i < MPEGDEC_MAX_CHANNELS); i++) {
		pcm[i] = fmalloc(MPEGDEC_PCM_SIZE * sizeof(INT16));
		if (!pcm[i]) {
			fprintf(stderr, "ERROR: Can't allocate PCM buffers\n");
			exit(1);
		}
	}

	if ((rawbuf = fmalloc(MPEGDEC_PCM_SIZE * sizeof(short) * 2)) == NULL) {
		fprintf(stderr, "ERROR: Can't allocate raw buffers\n");
		exit(1);
	}
	
	if (prebuflimit) {
		prebufsize = prebuflimit + (MPEGDEC_PCM_SIZE*sizeof(short)*2);
		if ((prebuffer = malloc(prebufsize)) == NULL) {
			fprintf(stderr, "ERROR: Can't allocate pre-buffer\n");
			exit(1);
		}
	}
	
	if ((dspfd = open(device, (O_WRONLY | O_CREAT | O_TRUNC), 0660)) < 0) {
		fprintf(stderr, "ERROR: Can't open output device '%s', "
			"errno=%d\n", device, errno);
		exit(0);
	}
	
	mpa_ctrl = mpa_defctrl;
	mpa_ctrl.bs_access = &bs_access;
	if (playstereo == 0)
		mpa_ctrl.layer_3.force_mono = 1;
	mpa_ctrl.layer_3.mono.quality = quality;
	mpa_ctrl.layer_3.stereo.quality = quality;

	mp3_buffer_offset = 0;
	mp3_buffer_next_block = 0;
	
//	mp3_filename = argv[1];
	mp3_filename = (char *)fn;
	
	mp3_stream_size = getstreamsize();
	mp3_fd = open(mp3_filename, O_RDONLY);
	
	if (mp3_fd < 0) {
		fprintf(stderr, "ERROR: Unable to open '%s', errno=%d\n",
			mp3_filename, errno);
		close_all();
		exit(0);
	}
	
	getnextbuffer();
	
mp3_restream:
	mps = MPEGDEC_open(mp3_filename, &mpa_ctrl);
	if (!mps) {
		fprintf(stderr, "ERROR: Unable to open MP3 Audio "
			"stream '%s'\n", mp3_filename);
		close_all();
		exit(0);
	}

	setdsp(dspfd, playstereo, playbits);
	
	/* Restart pre-buffering for next track */
	prebufnow = prebuflimit;
	prebufcnt = 0;
	ready = 1;
}

void play_frame( unsigned char *ply )
{
	if ( ready ) {
		*ply = 1;
		if((pcmcount = MPEGDEC_decode_frame(mps, pcm))<0) {
			printf("pcmcount =%d.\n", pcmcount);
			if(pcmcount==MPEGDEC_ERR_EOF) {
				/* Flush out any remaining buffer PCM data */
				flushpcm(dspfd);
				close_all();
				exit(0);
			}
		}
		writepcm(dspfd, pcm, pcmcount);
		*ply = 0;
	}
}

void play_forward( int f )
{
	if ( ( mp3_buffer_next_block + f*1024 ) < mp3_stream_size )
		mp3_buffer_next_block += f*1024;
}

void play_backward( int b )
{
		mp3_buffer_next_block -= b*1024;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -