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

📄 buffer.cpp

📁 一个KDE下的录音程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <errno.h>#include <fcntl.h>#include <qobject.h>#include <qlistbox.h>#include <kmessagebox.h>#include <klocale.h>#include "byteorder.h"#include "sound.h"#include "buffer.moc"extern KLocale      *globalKlocale;/* ---------------------------------------------------------------------- */voidxperror(const char *msg){    char text[256];    sprintf(text,"%s: %s", msg, strerror(errno));    KMessageBox::error(NULL, text);}/* ---------------------------------------------------------------------- */AudioBuffer::AudioBuffer(){    size = 0;    busy = 0;    position = 0;    clippedsamples = 0;}AudioBuffer::~AudioBuffer() {}int   AudioBuffer::is_busy()     { return busy; }void  AudioBuffer::balloc(void){    busy++;    if (busy != 1)	fprintf(stderr,"alloc: buffer reference count bug: %d\n",busy);}void  AudioBuffer::bfree(void){    busy--;    if (busy != 0)	fprintf(stderr,"free: buffer reference count bug: %d\n",busy);}int   AudioBuffer::start_write(struct SOUNDPARAMS*) { return 0; }void  AudioBuffer::stop_write() {}struct SOUNDPARAMS* AudioBuffer::get_params() { return NULL; }int   AudioBuffer::get_size() { return 0; }char* AudioBuffer::name() { return NULL; }void* AudioBuffer::read_audio(int len) { return 0; }int   AudioBuffer::write_audio(int len, void *data) { return 0; }int   AudioBuffer::seek(int pos) { return 0; }int   AudioBuffer::tell() { return 0; }/* ---------------------------------------------------------------------- */#define BUFFER_SIZE   0x10000#define BUFFER_MASK   0x0ffff#define BUFFER_SHIFT       16RAMBuffer::RAMBuffer(){    static int counter = 0;    memset(&params,0,sizeof(struct SOUNDPARAMS));    sprintf(bufname,"buffer #%d",++counter);    buffers = (char**)malloc(sizeof(void*));    buffers[0] = (char*)malloc(BUFFER_SIZE);    bufcount = 1;    position = 0;}RAMBuffer::~RAMBuffer(){    int i;    for (i = 0; i < bufcount; i++) {	free(buffers[i]);    }    free(buffers);}intRAMBuffer::start_write(struct SOUNDPARAMS *p){    memcpy(&params,p,sizeof(struct SOUNDPARAMS));    return 0;}void RAMBuffer::stop_write() {};struct SOUNDPARAMS*RAMBuffer::get_params(){    return &params;}intRAMBuffer::get_size(){    return size;}char*RAMBuffer::name(){    return bufname;}void*RAMBuffer::read_audio(int len){    /* FIXME (?): one can't read over buffer boundaries */    char *ptr;        if (position+len > size)	return NULL;    ptr  = buffers[position>>BUFFER_SHIFT];    ptr += (position&BUFFER_MASK);    position += len;    return ptr;}intRAMBuffer::write_audio(int len, void *data){    /* dito for write - not over buffer boundaries */    if ((position>>BUFFER_SHIFT) >= bufcount) {	buffers = (char**)realloc(buffers,sizeof(void*)*(bufcount+1));	if (NULL == (buffers[bufcount] = (char*)malloc(BUFFER_SIZE)))	    return -1;	bufcount++;    }    memcpy(buffers[position>>BUFFER_SHIFT]+(position&BUFFER_MASK), data, len);    position += len;    if (size < position)	size = position;    return 0;}intRAMBuffer::seek(int pos){    if (pos > size)	return -1;    position = pos;    return position;}intRAMBuffer::tell(){    return position;}/* ---------------------------------------------------------------------- */FileBuffer::FileBuffer(){    memset(&params,0,sizeof(struct SOUNDPARAMS));    fd = -1;    size = position = 0;    bstart = bstop = 0;}FileBuffer::~FileBuffer(){    if (fd == -1)	return;    close(fd);}voidFileBuffer::init_header(){    /* stolen from cdda2wav */    int nBitsPerSample = 8;    if (params.format == FMT_16BIT)	nBitsPerSample = 16;    unsigned long nBlockAlign = params.channels * ((nBitsPerSample + 7) / 8);    unsigned long nAvgBytesPerSec = nBlockAlign * params.rate;    unsigned long temp = /* data length */ 0 +	sizeof(WAVEHDR) - sizeof(CHUNKHDR);	    fileheader.chkRiff.ckid    = cpu_to_le32(FOURCC_RIFF);    fileheader.fccWave         = cpu_to_le32(FOURCC_WAVE);    fileheader.chkFmt.ckid     = cpu_to_le32(FOURCC_FMT);    fileheader.chkFmt.dwSize   = cpu_to_le32(16);    fileheader.wFormatTag      = cpu_to_le16(WAVE_FORMAT_PCM);    fileheader.nChannels       = cpu_to_le16(params.channels);    fileheader.nSamplesPerSec  = cpu_to_le32(params.rate);    fileheader.nAvgBytesPerSec = cpu_to_le32(nAvgBytesPerSec);    fileheader.nBlockAlign     = cpu_to_le16(nBlockAlign);    fileheader.wBitsPerSample  = cpu_to_le16(nBitsPerSample);    fileheader.chkData.ckid    = cpu_to_le32(FOURCC_DATA);    fileheader.chkRiff.dwSize  = cpu_to_le32(temp);    fileheader.chkData.dwSize  = cpu_to_le32(0 /* data length */);}intFileBuffer::attach(const char *file){    int new_file = 0;        if (-1 != fd)	close(fd);        ro = 0;    position = 0;    size = 0;    offset = sizeof(WAVEHDR);    strcpy(filename,file);    if (-1 == (fd = open(filename,O_RDWR))) {	if (errno == ENOENT) {	    if (-1 == (fd = open(filename,O_RDWR|O_CREAT,0666))) {		xperror(i18n("can't create wav file"));		return -1;	    }	    new_file = 1;	} else {	    if (-1 == (fd = open(filename,O_RDONLY))) {		xperror(i18n("can't open wav file"));		return -1;	    } else		ro = 1;	}    }    fcntl(fd,F_SETFD,FD_CLOEXEC);    if (!new_file) {	read(fd,&fileheader,offset);	if (!IS_STD_WAV_HEADER(fileheader)) {#if 0	    /* nice for debugging, but annonying for everyday usage */	    KMessageBox::error(NULL, i18n("not a wav file"));#endif	    return -1;	}	if (le16_to_cpu(fileheader.wFormatTag) != WAVE_FORMAT_PCM) {	    KMessageBox::error(NULL,i18n("unsupported audio format"));	    return -1;	}	params.format = FMT_8BIT;	if (16 == le16_to_cpu(fileheader.wBitsPerSample))	    params.format = FMT_16BIT;	params.channels = le16_to_cpu(fileheader.nChannels);	params.rate = cpu_to_le32(fileheader.nSamplesPerSec);	size = le32_to_cpu(fileheader.chkData.dwSize);    }    return 0;}intFileBuffer::start_write(struct SOUNDPARAMS *p){    memcpy(&params,p,sizeof(struct SOUNDPARAMS));    init_header();    lseek(fd,0,SEEK_SET);    write(fd,&fileheader,offset);    return 0;}voidFileBuffer::stop_write(){    unsigned long temp = size + sizeof(WAVEHDR) - sizeof(CHUNKHDR);    fileheader.chkRiff.dwSize = cpu_to_le32(temp);    fileheader.chkData.dwSize = cpu_to_le32(size);    lseek(fd,0,SEEK_SET);    write(fd,&fileheader,offset);}struct SOUNDPARAMS*FileBuffer::get_params(){    return &params;}intFileBuffer::get_size(){    return size;}char*FileBuffer::name(){    return filename;}void*FileBuffer::read_audio(int len){    int rc;        if (position+len > size)	return NULL;    /* printf("[%d - %d (+%d) - %d] / %d\n",bstart,position,len,bstop,size); */    if (position < bstart || position+len > bstop) {	rc = read(fd,buffer,65536);#if BYTE_ORDER == BIG_ENDIAN	if (params.format == FMT_16BIT) {	    /* byteswap 16bit pcm on bigendian machines */	    int i;	    char h;	    for (i = 0; i < rc; i += 2) {		h           = buffer[i];		buffer[i]   = buffer[i+1];		buffer[i+1] = h;	    }	}#endif	if (-1 == rc)	    return NULL;	bstart = position, bstop = position+rc;    }    position += len;    return buffer+position-bstart-len;}intFileBuffer::write_audio(int len, void *data){    int rc;#if BYTE_ORDER == BIG_ENDIAN    char *buf;    int  i;    if (params.format == FMT_16BIT) {	/* byteswap 16bit pcm on bigendian machines */	buf = (char*)malloc(len);	for (i = 0; i < len; i += 2) {	    buf[i] = ((char*)data)[i+1];	    buf[i+1] = ((char*)data)[i];	}	rc = write(fd,buf,len);	free(buf);    } else {	rc = write(fd,data,len);    }#else    rc = write(fd,data,len);#endif    if (len == rc) {	position += len;	if (position > size)	    size = position;	return 0;    } else	return -1;}intFileBuffer::seek(int pos){    if (pos > size)	return -1;    position = pos;    if (-1 == lseek(fd,position+offset,SEEK_SET))	perror("fb: lseek");    return 0;}intFileBuffer::tell(){    return position;}/* ---------------------------------------------------------------------- */BufferList::BufferList(QListBox *l, Soundcard *c){    listbox   = l;    card      = c;    count     = 0;    brecord   = -1;    bplayback = -1;    mon       = 0;    level     = 0;    wait      = 0;    new_buffer_count = 0;    connect(card,SIGNAL(newparams(struct SOUNDPARAMS*)),	    this, SLOT(new_params(struct SOUNDPARAMS*)));    connect(card,SIGNAL(senddata(void*)),	    this, SLOT(new_data(void*)));    connect(card,SIGNAL(receivedata(void*)),	    this, SLOT(post_data(void*)));}intBufferList::add_filebuffer(const char *filename){    FileBuffer *fbuffer;    fbuffer = new FileBuffer();    if (-1 == fbuffer->attach(filename)) {	delete fbuffer;	return -1;    }    add_buffer(fbuffer);    return 0;}

⌨️ 快捷键说明

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