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

📄 dspfile.c

📁 音频压缩解压缩软件
💻 C
字号:
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <fcntl.h>
#include <malloc.h>
#include <string.h>
#include <memory.h>

#include <sys/types.h>
#include <sys/ioctl.h>
#include <linux/soundcard.h>
#include "WAVfile.h"
#include "DSPfile.h"
#include "def.h"
#include "g711.h"

#define AUDIODEV	"/dev/sound/dsp"		/* Default pathname for audio device */
char *env_AUDIODEV = AUDIODEV;				/* Default compiled in audio device */

/*
 * Open /dev/dsp for reading or writing:
 */
DSPFILE *
OpenDSP(WAVFILE *wfile,int omode) {

	int t;					/* Work int */
	unsigned long ul;			/* Work unsigned long */
	DSPFILE *dfile = (DSPFILE *) malloc(sizeof (DSPFILE));

	if ( dfile == NULL ) {
		printf("Opening DSP device");
		return NULL;
	}

	memset(dfile,0,sizeof *dfile);
	dfile->dspbuf = NULL;

	/*
	 * Open the device driver:
	 */
	if ( (dfile->fd = open(env_AUDIODEV,omode,0)) < 0 ) {
		printf("nOpening audio device");
		goto errxit;
	}



        /*
         * Determine the audio device's block size.  Should be done after
         * setting sampling rate etc.
         */
        dfile->dspblksiz=4096;
 
        /*
         * Allocate a buffer to do the I/O through:
         */
        if ( (dfile->dspbuf = (char *) malloc(dfile->dspblksiz)) == NULL ) {
                printf("For DSP I/O buffer");
                goto errxit;
        }



	/*
	 * Set the data bit size:
	 */
	t = 2*(wfile->DataBits);

        if ( ioctl(dfile->fd,SNDCTL_DSP_SAMPLESIZE,&t) < 0 ) {
		printf("Setting DSP bits");
		goto errxit;
	}


	/*
	 * Set the mode to be Stereo or Mono:
	 */
	t = wfile->Channels == Stereo ? 1 : 0;
	if ( ioctl(dfile->fd,SNDCTL_DSP_STEREO,&t) < 0 ) {
		printf("Unable to set DSP mode");
		goto errxit;
	}		
      
	/*
	 * Set the sampling rate:
	 */
	ul = wfile->SamplingRate;
	if ( ioctl(dfile->fd,SNDCTL_DSP_SPEED,&ul) < 0 ) {
		printf("Unable to set audio sampling rate");
		goto errxit;
	}

	/*
	 * Return successfully opened device:
	 */
	return dfile;				/* Return file descriptor */

	/*
	 * Failed to open/initialize properly:
	 */
errxit:	
	if ( dfile->fd >= 0 )
		close(dfile->fd);		/* Close device */
	if ( dfile->dspbuf != NULL )
		free(dfile->dspbuf);
	free(dfile);
	return NULL;				/* Return error indication */
}

/*
 * Close the DSP device:
 */
int
CloseDSP(DSPFILE *dfile) {
	int fd;

	if ( dfile == NULL ) {
		printf("DSPFILE is not open");
		return -1;
	}

	fd = dfile->fd;
	if ( dfile->dspbuf != NULL )
		free(dfile->dspbuf);
	free(dfile);
	
	if ( close(fd) ) {
		printf("Closing DSP fd");
		return -1;
	}

	return 0;
}

/*
 * Play DSP from WAV file:
 */
int
PlayDSP(DSPFILE *dfile,WAVFILE *wfile) {
	UInt32 byte_count = (UInt32) wfile->Samples;
	int bytes;
	int  n,i;
	int byte_modulo;
	unsigned char pcmbuf;
	unsigned char alawbuf[4096];
	unsigned char pcm_short[2];
	short a_law;
	/*
	 * Check that the WAVFILE is open for reading:
	 */
	if ( wfile->rw != 'R' ) {
		printf("WAVFILE must be open for reading");
		return -1;
	}

	/*
	 * First determine how many bytes are required for each channel's sample:
	 */
	byte_count = 1;/*8bit*/


	/*
	 * Allow for Mono/Stereo difference:
	 */
	if ( wfile->Channels == Stereo)
		byte_count *= 2;		/* Twice as many bytes for stereo */
	else if ( wfile->Channels != Mono) {
		printf("DSPFILE control block is corrupted (chan_mode)");
		return -1;
	}		

	byte_modulo = byte_count;				/* This many bytes per sample */
	byte_count  = wfile->Samples * byte_modulo;	/* Total bytes to process */
 
  

	if ( ioctl(dfile->fd,SNDCTL_DSP_SYNC,0) != 0 )
		printf("ioctl  SNDCTL_DSP_SYNC");

        /* Seek to requested start sample */
        lseek(wfile->fd,wfile->DataStart,SEEK_SET);
 
	for(;byte_count>0;byte_count-=bytes)
		{
		bytes=byte_count>2048?2048:byte_count;

		/*pcm alaw change*/
		for(i=0;i<bytes;i++)
		{
		if(read(wfile->fd,&pcmbuf,1)<0)goto errxit;
		a_law=(short)ALawDecode(pcmbuf);	
              alawbuf[2*i]=(unsigned char)a_law;
		alawbuf[2*i+1]=(unsigned char)(a_law>>8);	
		}
		if ( write(dfile->fd,alawbuf,4096) <0)goto errxit;
             }
		printf("play over");

			

        
errxit:	return -1;	/* Indicate error return */
}

/*
 * Record DSP to WAV file: If samples == 0UL, then record continues until
 * a bRecordStopPosted becomes true (via SIGINT).
 */
int
RecordDSP(DSPFILE *dfile,WAVFILE *wfile,UInt32 samples) {
	UInt32 byte_count = (UInt32) wfile->Samples;
	UInt32 chunk;
	int bytes;
	int n,i;
	UInt32 bytes_per_sample = 0;
	UInt32 bytes_written = 0;
	unsigned char pcm_bytes[2];
	unsigned char a_law;
	unsigned char pcmbuf;
	short pcm;
	/*
	 * Check that the WAVFILE is open for writing:
	 */
	if ( wfile->rw != 'W' ) {
		printf("WAVFILE must be open for writing");
		return -1;
	}

	/*
	 * First determine how many bytes are required for each channel's sample:
	 */

	byte_count = 1;/*8bit*/

	/*
	 * Allow for Mono/Stereo difference:
	 */
	if ( wfile->Channels == Stereo)
		byte_count *= 2;		/* Twice as many bytes for stereo */
	else if ( wfile->Channels != Mono) {
		printf("DSPFILE control block is corrupted (chan_mode)");
		return -1;
	}		

	bytes_per_sample = byte_count;		/* Save for close later */

	if ( samples > 0 )
		byte_count *= wfile->Samples;	/* Total number of bytes to collect */


		/*pam a law chang*/
		for(i =0; i<byte_count; i++)
	      {
	       if(read(dfile->fd,&pcmbuf,1)<0)goto errxit;
		pcm_bytes[0] = pcmbuf;
		if(read(dfile->fd,&pcmbuf,1)<0)goto errxit;
		pcm_bytes[1] =pcmbuf;
		pcm = *(short *)&pcm_bytes;
		a_law	 = ALawEncode((int)pcm);
		if(write(wfile->fd,&a_law,1)<0)goto errxit;
		
	       }

		bytes_written += byte_count;


	printf("record close!");
	
	wfile->Samples = bytes_written & ~(bytes_per_sample-1);
	return 0;	/* All samples played successfully */

errxit:	wfile->Samples = bytes_written & ~(bytes_per_sample-1);
	return -1;	/* Indicate error return */
}

⌨️ 快捷键说明

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