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

📄 audioinput.cpp

📁 改写的qtopia录音放音程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/************************************************************************ Copyright (C) 2000-2002 Trolltech AS.  All rights reserved.**** This file is part of the Qtopia Environment.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include <stdlib.h>#include <qsocketnotifier.h>#include "audioinput.h"#ifdef Q_WS_WIN#include <windows.h>#include <mmsystem.h>#include <mmreg.h>#endif#if defined(Q_WS_X11) || defined(Q_WS_QWS)#include <fcntl.h>#include <sys/ioctl.h>#include <sys/soundcard.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/types.h>#include <unistd.h>#include <errno.h>// The OSS device to record from.#define	AUDIO_RECORD_SOURCE	SOUND_MIXER_MIC#endif// Sound formats, for use by AudioFormatHandler::create().#ifndef AFMT_U8#define AFMT_U8                 0x00000008#define AFMT_S16_LE             0x00000010#define AFMT_S16_BE             0x00000020#define AFMT_S8                 0x00000040#define AFMT_U16_LE             0x00000080#define AFMT_U16_BE             0x00000100#endif// Conversion handler for an audio input format.  Format handlers// are responsible for converting from the device's encoding to// normalized 16-bit host byte order samples.class AudioFormatHandler{public:    virtual ~AudioFormatHandler() { }    // Get the read size for a specific number of raw sound samples.    virtual unsigned int readSize( unsigned int length ) = 0;    // Convert a buffer of audio data into raw 16-bit sound samples.    // "length" is the number of bytes read from the device.  Returns    // the number of raw sound samples.    virtual int convert( short *buffer, int length ) = 0;    // Create the appropriate conversion handler for a device format.    static AudioFormatHandler *create( int format );};// Convert signed 16-bit samples to normalized raw samples.  This doesn't// need to do anything, as the incoming data is already normalized.class S16AudioFormatHandler : public AudioFormatHandler{public:    unsigned int readSize( unsigned int length ) { return length * 2; }    int convert( short *, int length )           { return length / 2; }};// Convert signed 16-bit samples to normalized raw samples by byte-swapping.class S16SwapAudioFormatHandler : public AudioFormatHandler{public:    unsigned int readSize( unsigned int length ) { return length * 2; }    int convert( short *buffer, int length );};int S16SwapAudioFormatHandler::convert( short *buffer, int length ){    int result = length / 2;    while ( length >= 2 ) {	*buffer = (short)((*buffer << 8) | ((*buffer >> 8) & 0xFF));	++buffer;	length -= 2;    }    return result;}// Convert unsigned 16-bit samples to normalized raw samples.class U16AudioFormatHandler : public AudioFormatHandler{public:    unsigned int readSize( unsigned int length ) { return length * 2; }    int convert( short *buffer, int length );};int U16AudioFormatHandler::convert( short *buffer, int length ){    int result = length / 2;    while ( length >= 2 ) {	*buffer += (short)0x8000;	++buffer;	length -= 2;    }    return result;}// Convert unsigned 16-bit samples to normalized raw samples and byte-swap.class U16SwapAudioFormatHandler : public AudioFormatHandler{public:    unsigned int readSize( unsigned int length ) { return length * 2; }    int convert( short *buffer, int length );};int U16SwapAudioFormatHandler::convert( short *buffer, int length ){    int result = length / 2;    while ( length >= 2 ) {	*buffer = (short)(((*buffer << 8) | ((*buffer >> 8) & 0xFF)) + 0x8000);	++buffer;	length -= 2;    }    return result;}// Convert unsigned 8-bit samples to normalized raw samples.class U8AudioFormatHandler : public AudioFormatHandler{public:    unsigned int readSize( unsigned int length ) { return length; }    int convert( short *buffer, int length );};int U8AudioFormatHandler::convert( short *buffer, int length ){    int result = length;    unsigned char *buf = (((unsigned char *)buffer) + length);    buffer += length;    while ( length > 0 ) {	*(--buffer) = (short)((((int)(*(--buf))) - 128) << 8);	--length;    }    return result;}// Convert signed 8-bit samples to normalized raw samples.class S8AudioFormatHandler : public AudioFormatHandler{public:    unsigned int readSize( unsigned int length ) { return length; }    int convert( short *buffer, int length );};int S8AudioFormatHandler::convert( short *buffer, int length ){    int result = length;    unsigned char *buf = (((unsigned char *)buffer) + length);    buffer += length;    while ( length > 0 ) {	*(--buffer) = (short)(((int)(*(--buf))) << 8);	--length;    }    return result;}AudioFormatHandler *AudioFormatHandler::create( int format ){    // Determine if the host is little-endian or big-endian.    union    {        short v1;        char  v2[2];    } un;    un.v1 = 0x0102;    bool littleEndian = ( un.v2[0] == 0x02 );    // Construct an appropriate handler from the incoming format.    switch ( format ) {	case AFMT_U8:	    return new U8AudioFormatHandler;	case AFMT_S16_LE:	    if ( littleEndian )		return new S16AudioFormatHandler;	    else		return new S16SwapAudioFormatHandler;	case AFMT_S16_BE:	    if ( littleEndian )		return new S16SwapAudioFormatHandler;	    else		return new S16AudioFormatHandler;	case AFMT_S8:	    return new S8AudioFormatHandler;	case AFMT_U16_LE:	    if ( littleEndian )		return new U16AudioFormatHandler;	    else		return new U16SwapAudioFormatHandler;	case AFMT_U16_BE:	    if ( littleEndian )		return new U16SwapAudioFormatHandler;	    else		return new U16AudioFormatHandler;	default:	    qDebug( "unknown audio input format - assuming signed 16-bit" );	    return new S16AudioFormatHandler;    }}// Perform channel doubling to convert mono samples into stereo.class MToSAudioFormatHandler : public AudioFormatHandler{public:    MToSAudioFormatHandler( AudioFormatHandler *_linked ) { linked = _linked; }    ~MToSAudioFormatHandler() { delete linked; }    unsigned int readSize( unsigned int length )	{ return linked->readSize( length ); }    int convert( short *buffer, int length );private:    AudioFormatHandler *linked;};int MToSAudioFormatHandler::convert( short *buffer, int length ){    // Convert the raw samples into their normalized 16-bit form.    int samples = linked->convert( buffer, length );    // Perform doubling on the the samples.    int posn = samples * 2;    while ( posn > 0 ) {	posn -= 2;	buffer[posn] = buffer[posn + 1] = buffer[posn / 2];    }    return samples * 2;}// Perform channel averaging to convert stereo samples into mono.class SToMAudioFormatHandler : public AudioFormatHandler{public:    SToMAudioFormatHandler( AudioFormatHandler *_linked ) { linked = _linked; }    ~SToMAudioFormatHandler() { delete linked; }    unsigned int readSize( unsigned int length )	{ return linked->readSize( length ); }    int convert( short *buffer, int length );private:    AudioFormatHandler *linked;};int SToMAudioFormatHandler::convert( short *buffer, int length ){    // Convert the raw samples into their normalized 16-bit form.    int samples = linked->convert( buffer, length );    // Perform averaging on the the samples.    int posn = 0;    int limit = samples / 2;    while ( posn < limit ) {	buffer[posn] = (short)(((int)(buffer[posn * 2])) +			       ((int)(buffer[posn * 2 + 1])) / 2);	++posn;    }    return limit;}// Resample an audio stream to a different frequency.class ResampleAudioFormatHandler : public AudioFormatHandler{public:    ResampleAudioFormatHandler( AudioFormatHandler *_linked,				int _from, int _to, int _channels,				int bufferSize );    ~ResampleAudioFormatHandler() { delete linked; delete[] temp; }    unsigned int readSize( unsigned int length )	{ return linked->readSize( length ); }    int convert( short *buffer, int length );private:    AudioFormatHandler *linked;    int from, to, channels;    long samplesDue;    long rollingLeft;    long rollingRight;    int numInRolling;    short *temp;};ResampleAudioFormatHandler::ResampleAudioFormatHandler	( AudioFormatHandler *_linked, int _from, int _to,	  int _channels, int bufferSize ){    linked = _linked;    from = _from;    to = _to;    channels = _channels;    samplesDue = 0;    rollingLeft = 0;    rollingRight = 0;    numInRolling = 0;    temp = new short [bufferSize];}int ResampleAudioFormatHandler::convert( short *buffer, int length ){    // Convert the raw samples into their normalized 16-bit form.    int samples = linked->convert( buffer, length );    if ( !samples )	return 0;    // Resample the data.  We should probably do some kind of curve    // fit algorithm, but that can be *very* expensive CPU-wise.    memcpy( temp, buffer, samples * sizeof(short) );    int inposn = 0;    int outposn = 0;    short left, right;    long due = samplesDue;    long rollLeft = rollingLeft;    long rollRight = rollingRight;    int num = numInRolling;    if ( from < to ) {	// Replicate samples to convert to a higher sample rate.	if ( channels == 1 ) {	    while ( inposn < samples ) {		due += to;		left = temp[inposn++];		while ( due >= from ) {		    buffer[outposn++] = left;		    due -= from;		}	    }	} else {	    while ( inposn < samples ) {		due += to;		left = temp[inposn++];		right = temp[inposn++];		while ( due >= from ) {		    buffer[outposn++] = left;		    buffer[outposn++] = right;		    due -= from;		}	    }	}    } else {	// Average samples to convert to a lower sample rate.	// This may lose a small number (from / to) of samples	// off the end of the stream.	if ( channels == 1 ) {	    while ( inposn < samples ) {		left = temp[inposn++];		rollLeft += (long)left;		due += to;		++num;		if ( due >= from ) {		    buffer[outposn++] = (short)(rollLeft / num);		    rollLeft = 0;		    num = 0;		    due -= from;		}	    }	} else {	    while ( inposn < samples ) {		left = temp[inposn++];		right = temp[inposn++];		rollLeft += (long)left;		rollLeft += (long)right;		due += to;		++num;		if ( due >= from ) {		    buffer[outposn++] = (short)(rollLeft / num);		    buffer[outposn++] = (short)(rollRight / num);

⌨️ 快捷键说明

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