?? speaker.c
字號:
/* -*- C++ -*- * Speaker.C - source file for class Speaker * Copyright (c) 1998 Joe Yandle <joe@wlcg.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */#include "Speaker.h"#include "GtkView.h"#include <sys/soundcard.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <stdio.h>#include <fcntl.h>#include <string.h>#include <unistd.h>Speaker::Speaker(GtkView* v){ view = v;}void Speaker::playWav(const String& wavFile){ FILE* fp; char chunkID[5]; long chunkSize; short wFormatTag; unsigned short wChannels; unsigned long dwSamplesPerSec; unsigned long dwAvgBytesPerSec; unsigned short wBlockAlign; unsigned short wBitsPerSample; char groupID[8], riffType[5]; unsigned char* wavBuf; int bufSize; int dsp; long startData; if((dsp=open(DEV,O_WRONLY))==-1) { view->display("Error opening device", DEV, true, 10); return; } if (ioctl(dsp, SNDCTL_DSP_SYNC, 0)==-1) { view->display("Error syncing device", DEV, true, 10); close(dsp); return; } if(!(fp = fopen(wavFile.cstr(), "r"))) { close(dsp); return; } fread(groupID,sizeof(char),8,fp); fread(riffType,sizeof(char),4,fp); groupID[4]=0; riffType[4]=0; chunkID[4]=0; fread(chunkID,sizeof(char),4,fp); fread(&chunkSize,sizeof(long),1,fp); fread(&wFormatTag,sizeof(short),1,fp); fread(&wChannels,sizeof(unsigned short),1,fp); fread(&dwSamplesPerSec,sizeof(unsigned long),1,fp); fread(&dwAvgBytesPerSec,sizeof(unsigned long),1,fp); fread(&wBlockAlign,sizeof(unsigned short),1,fp); fread(&wBitsPerSample,sizeof(unsigned short),1,fp); bufSize = dwSamplesPerSec*wBlockAlign/4; wavBuf = new unsigned char[bufSize]; int bits = wBitsPerSample; int samples = dwSamplesPerSec; int channels = wChannels; ioctl(dsp, SOUND_PCM_WRITE_BITS, &bits); ioctl(dsp, SOUND_PCM_WRITE_RATE, &samples); ioctl(dsp, SOUND_PCM_WRITE_CHANNELS, &channels);#ifdef SOUND_DEBUG printf("Sample size: %d bits\n", bits); printf("Sample rate: %d Hz\n", samples); if(channels == 1) printf("Sample mode: mono\n"); else if(channels == 2) printf("Sample mode: stereo\n");#endif if(wBitsPerSample == 16) { int format = AFMT_S16_LE; ioctl(dsp, SOUND_PCM_SETFMT, &format); } else if(wBitsPerSample == 8) { int format = AFMT_U8; ioctl(dsp, SOUND_PCM_SETFMT, &format); } while(!strstr(chunkID, "data")) { fread(&chunkID,sizeof(char),4,fp); chunkID[4]=0; fread(&chunkSize,sizeof(long),1,fp); if(!strstr(chunkID,"data")) { fseek(fp, chunkSize, SEEK_CUR); } } startData = ftell(fp); struct stat s; stat(wavFile.cstr(),&s); long fileSize = s.st_size; int bufs; int lastBufSize; if(startData+chunkSize > fileSize) { bufs = (fileSize-startData)/bufSize; lastBufSize = (fileSize-startData)%bufSize; } else { bufs = chunkSize/bufSize; lastBufSize = chunkSize%bufSize; } for(int i=0; i<bufs; i++) { view->handleEvents(); fread(wavBuf, sizeof(unsigned char), bufSize, fp); write(dsp,wavBuf,bufSize); } fread(wavBuf, sizeof(unsigned char), lastBufSize, fp); write(dsp,wavBuf,lastBufSize); fclose(fp); close(dsp);}void Speaker::recWav(const String& wavFile){ char recFile[256]; char tempRecFile[256]; int recBitsPerSample = 16; int recSamplesPerSec = 8000; int recNumChannels = 1; double recSecFraction = 0.25; strcpy(recFile, wavFile.cstr()); sprintf(tempRecFile, "%s.raw", recFile); FILE* fp; FILE* recfp; int numRead = 0; int dsp; char groupID[8], riffType[5], chunkID[5]; long chunkSize; short wFormatTag; unsigned short wChannels; unsigned long dwSamplesPerSec; unsigned long dwAvgBytesPerSec; unsigned short wBlockAlign; unsigned short wBitsPerSample; int arg; if(view->getRecOn()) return; if((fp = fopen(tempRecFile, "w+")) == NULL) return; if((dsp = open(DEV, O_RDONLY)) == -1) return; arg = recBitsPerSample; ioctl(dsp, SOUND_PCM_WRITE_BITS, &arg); arg = recSamplesPerSec; ioctl(dsp, SOUND_PCM_WRITE_RATE, &arg); arg = recNumChannels; ioctl(dsp, SOUND_PCM_WRITE_CHANNELS, &arg); view->setRecOn(true); int bufSize = (int)(recSecFraction*recSamplesPerSec*recNumChannels*recBitsPerSample/8); unsigned char* recBuf = new unsigned char[bufSize]; while(view->getRecOn()) { view->handleEvents(); read(dsp, recBuf, bufSize); fwrite(recBuf, sizeof(unsigned char), bufSize, fp); numRead += bufSize; } fclose(fp); fp = fopen(tempRecFile, "r+"); recfp = fopen(recFile, "w+"); strcpy(groupID, "RIFF"); strcpy(riffType, "WAVE"); strcpy(chunkID, "fmt "); chunkSize = 16; wFormatTag = 1; wChannels = recNumChannels; dwSamplesPerSec = recSamplesPerSec; wBlockAlign = recNumChannels*recBitsPerSample/8; dwAvgBytesPerSec = recSamplesPerSec*wBlockAlign; wBitsPerSample = recBitsPerSample; fwrite(groupID,sizeof(char),8,recfp); fwrite(riffType,sizeof(char),4,recfp); fwrite(chunkID,sizeof(char),4,recfp); fwrite(&chunkSize,sizeof(long),1,recfp); fwrite(&wFormatTag,sizeof(short),1,recfp); fwrite(&wChannels,sizeof(unsigned short),1,recfp); fwrite(&dwSamplesPerSec,sizeof(unsigned long),1,recfp); fwrite(&dwAvgBytesPerSec,sizeof(unsigned long),1,recfp); fwrite(&wBlockAlign,sizeof(unsigned short),1,recfp); fwrite(&wBitsPerSample,sizeof(unsigned short),1,recfp); strcpy(chunkID, "data"); chunkSize = numRead; fwrite(chunkID,sizeof(char),4,recfp); fwrite(&chunkSize,sizeof(long),1,recfp); for(int i=0; i< numRead; i+= bufSize) { fread(recBuf, sizeof(char), bufSize, fp); fwrite(recBuf, sizeof(char), bufSize, recfp); } fclose(fp); fclose(recfp); //remove(tempRecFile); char temp1[256]; sprintf(temp1, "Finished recording: %d bytes", numRead); view->display(temp1, NULL, true, 0); close(dsp); }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -