📄 dspfile.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 + -