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

📄 speaker.c

📁 语音Email/语音Modem程序包
💻 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 + -