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

📄 srec.cc

📁 linux下录音程序
💻 CC
字号:
/* * wavrec/mpegrec for Linux ( Direct-to-disk WAV file and MP3 capture ) *                          ( MP3 is available via lame: www.sulaco.org/mp3 ) * Developed by Andrew L. Sandoval -- sandoval@netwaysglobal.com -- Feb. 2000 * * Copyright (C) 2000 Andrew L. Sandoval *  *  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 <iostream>#include <string>#include <vector>#include <deque>#include <cstring>#include <map>extern "C"{ #include <stdio.h> #include <unistd.h> #include <sys/ioctl.h> #include <sys/soundcard.h> #include <pthread.h> #include <signal.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <errno.h>}#define BUFFER_SIZE	65535#define MIN_BUFFERS	10struct SndBuffer{	unsigned long used;	unsigned char buffer[BUFFER_SIZE];};#define WAV_ID_RIFF 0x46464952 /* "RIFF" */#define WAV_ID_WAVE 0x45564157 /* "WAVE" */#define WAV_ID_FMT  0x20746d66 /* "fmt " */#define WAV_ID_DATA 0x61746164 /* "data" */#define WAV_ID_PCM  0x0001struct WaveHeader{	unsigned long riff;	unsigned long file_length;	unsigned long wave;	unsigned long fmt;	unsigned long fmt_length;	short fmt_tag;	short channels;	unsigned long sample_rate;	unsigned long bytes_per_second;	short block_align;	short bits;	unsigned long data;	unsigned long data_length;};struct WaveHeader genericWaveHeader = { WAV_ID_RIFF, 0xFFFFFFFF, WAV_ID_WAVE,										WAV_ID_FMT, 16, WAV_ID_PCM, 										2, 44100, 192000,										4, 16, WAV_ID_DATA,										0xFFFFFFFF };deque <struct SndBuffer *> inputBuffers;deque <struct SndBuffer *> fullBuffers;unsigned long seconds = 0; 	//Ctrl-C to stopunsigned long bytesPerSecond = 44100 * 2 *2;int recordingNow = 0;int doneRecording = 0;int stopRequested = 0;int	binitialized = 0;pthread_mutex_t fullBuffersLock  = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t inputBuffersLock = PTHREAD_MUTEX_INITIALIZER;int outputFd = 1;static void stop(int signal){	stopRequested++;}unsigned long shipToEncoder(unsigned long *processed){ unsigned long lastSize; pthread_mutex_lock( &fullBuffersLock ); lastSize = fullBuffers.size(); if(!lastSize) {	  pthread_mutex_unlock( &fullBuffersLock ); 	  if(processed) *processed = 0;	  return lastSize; } struct SndBuffer *sndbuf = fullBuffers[0]; fullBuffers.pop_front(); pthread_mutex_unlock( &fullBuffersLock ); write( outputFd, reinterpret_cast<void*>(sndbuf->buffer), sndbuf->used ); if(processed) *processed = sndbuf->used; lastSize--; delete sndbuf; return lastSize;}static void *encode(void *arg){  unsigned long lastSize = 1;  unsigned long bytesProcessed = 0;  unsigned long Processed = 0;  while(!doneRecording || lastSize)  {		  lastSize = shipToEncoder(&Processed);		  bytesProcessed += Processed;		  if( bytesProcessed > (bytesPerSecond /2) )		  {				cerr << ".";				bytesProcessed = 0;		  }		  if(!lastSize)		  {				  sched_yield();				  continue;		  }  }}static void *prepareBuffers(void *arg){ while(1) {		 // Prepare enough input buffers for one second: 		unsigned long onesecond = bytesPerSecond / BUFFER_SIZE;		onesecond++;		for(int i=0; i < onesecond; i++)		{ 				struct SndBuffer *buffer = new SndBuffer;			   	memset( reinterpret_cast<void*>(buffer), 0, sizeof(SndBuffer) );				pthread_mutex_lock( &inputBuffersLock );			   	inputBuffers.push_back( buffer );				pthread_mutex_unlock( &inputBuffersLock );	   	}		pthread_mutex_lock( &inputBuffersLock );		unsigned long sz = inputBuffers.size();		pthread_mutex_unlock( &inputBuffersLock );		binitialized = 1;		while(sz > MIN_BUFFERS)		{				sched_yield();				pthread_mutex_lock( &inputBuffersLock );				sz = inputBuffers.size();				pthread_mutex_unlock( &inputBuffersLock );		} } return NULL;}int main(int argc, char *argv[]){ unsigned long rate = 44100; char *mpg_bitrate = "192"; unsigned long argument_error = 0; string outputFile = "-"; string encoderProcess = "lame"; string encoderExtraFlags = ""; int userSuppliedEncoder = 0; int userSuppliedEncoderExtras = 0; FILE *lame_encoder = NULL;  int mpegrec = 0; if(strstr(argv[0], "mpegrec")) mpegrec++; cerr << argv[0]       << "  Copyright (C) 2000 Andrew L. Sandoval" << endl       << "This program comes with ABSOLUTELY NO WARRANTY." << endl <<      "See the file COPYING (http://www.gnu.org/copyleft/gpl.txt) for details."       << endl << endl; for(int i=1; i<argc; i++) {	if(!strcmp(argv[i], "-l") && argc>i)	{			seconds = atol(argv[i+1]);			++i;			continue;	}	if(!strcmp(argv[i], "-r") && argc>1)	{			rate = atol(argv[i+1]);			++i;			continue;	}	if(!strcmp(argv[i], "-e") && argc>1)	{			encoderProcess = string(argv[i+1]);			userSuppliedEncoder = 1;			++i;			continue;    }	if(!strcmp(argv[i], "-x") && argc>1)	{			encoderExtraFlags = string(argv[i+1]);			userSuppliedEncoderExtras = 1;			++i;			continue;    }	if(!strcmp(argv[i], "-o") && argc>1)	{			outputFile = string(argv[i+1]);			++i;			continue;	}	if(!strcmp(argv[i], "-b") && argc>1)	{			mpg_bitrate = argv[i+1];			++i;			continue;	}	if(!strcmp(argv[i], "--help") || !strcmp(argv[i], "-?"))	{			argument_error++;			break;	}	cerr << "Unknown argument: '" << argv[i] << "'" << endl;	argument_error++; } if(argument_error) {	cerr << endl << "USAGE: " << argv[0] << " [options]" << endl	<< "Options:" << endl	<< "	-b mp3_bitrate_in_kHz (for mpegrec only - default is 192)" << endl	<< "	-e encoder_process (for mpegrec only - default is \"lame\")" << endl	<< "	-l length_in_seconds  (default is to continue until ctrl-c)" << endl	<< "	-r rate               (default is 44100)" << endl	<< "	-o outputfilename     (default is stdout or \"-\")" << endl	<< "	-x extraEncoderFlags  (default is \"\")" << endl	<< endl;	return 1; } bytesPerSecond = rate * 2 * 2;  // rate * 16-bits * stereo genericWaveHeader.sample_rate = rate; genericWaveHeader.bytes_per_second = bytesPerSecond; unsigned long hdrSeconds = seconds ? seconds : 3600 * 24;  //24hr Max. genericWaveHeader.data_length = bytesPerSecond * (hdrSeconds + 1); genericWaveHeader.file_length = genericWaveHeader.data_length +								 sizeof(genericWaveHeader); // Setup the signal handler so we stop on CTRL-C signal( SIGHUP, stop ); signal( SIGINT, stop ); signal( SIGQUIT, stop ); signal( SIGTERM, stop ); signal( SIGPIPE, stop );  // Start the buffer supply thread... pthread_t prepbufThread; pthread_create( &prepbufThread, NULL, prepareBuffers, NULL); while( !binitialized ) sched_yield();  //Give prepareBuffers a chance  // Begin recording and continue until recordingNow = 0 or bytes of input // equals seconds requested... unsigned long totalBytesRequested = 0; if(seconds) totalBytesRequested = seconds * bytesPerSecond; // If output file is specified and this is NOT an argument of mpegrec // open the output file: if(!mpegrec) {	if( outputFile != string("-") )	{		outputFd = open( outputFile.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644 );		if(outputFd == -1)		{			perror( outputFile.c_str() );			return 1;		}	} } else // mpegrec: {	if(!userSuppliedEncoder)	{		encoderProcess += " -ms -b ";		encoderProcess += mpg_bitrate;		if(userSuppliedEncoderExtras) 		{			encoderProcess += " ";			encoderProcess += encoderExtraFlags;		}		encoderProcess += " - ";		encoderProcess += outputFile;	}	else	{		if(userSuppliedEncoderExtras) 		{			encoderProcess += " ";			encoderProcess += encoderExtraFlags;		}	}	cerr << "Streaming " << rate << "Hz WAV data to:" << endl          << encoderProcess << endl << flush;	lame_encoder = popen( encoderProcess.c_str(), "w" );	if(!lame_encoder)	{		perror( encoderProcess.c_str() );		return 1;	}	outputFd = fileno( lame_encoder ); } // // Open the sound card // int dsp = open( "/dev/dsp", O_RDONLY ); if(dsp == -1) {		 perror( "/dev/dsp" );		 return 1; } // Reset the card, set the format, stereo, and speed... ioctl( dsp, SNDCTL_DSP_RESET, 0); int format = AFMT_S16_LE; if( ioctl(dsp, SNDCTL_DSP_SETFMT, &format) == -1) {	perror( "SNDCTL_DSP_SETFMT" );	return 1; } int stereo = 1; if( ioctl(dsp, SNDCTL_DSP_STEREO, &stereo) == -1) {	perror( "SNDCTL_DSP_STEREO" );	return 1; } int samplerate = rate; if( ioctl(dsp, SNDCTL_DSP_SPEED, &samplerate) == -1) {	perror( "SNDCTL_DSP_SPEED" );	return 1; } // // Begin Recording... // cerr << endl; recordingNow = 1; // // Write the WAV Header (generic because the length is MAX) // write( outputFd, reinterpret_cast<void*>(&genericWaveHeader),	    sizeof(genericWaveHeader) );  // Start the encode supply thread... pthread_t encodeThread; pthread_create( &encodeThread, NULL, encode, NULL); unsigned long bytesRead = 0;  while(1) {		 pthread_mutex_lock( &inputBuffersLock );		 struct SndBuffer *buf = inputBuffers[0];		 if(!buf)		 {				 pthread_mutex_unlock( &inputBuffersLock );				 cerr << "No inputBuffers!" << endl;				 buf = new SndBuffer;				 buf->used = 0;		 }		 else inputBuffers.pop_front();		 pthread_mutex_unlock( &inputBuffersLock );		 buf->used = read( dsp, reinterpret_cast<void*>(buf->buffer),						   BUFFER_SIZE );		 bytesRead += buf->used;		 pthread_mutex_lock( &fullBuffersLock );		 fullBuffers.push_back( buf );		 pthread_mutex_unlock( &fullBuffersLock );		 if( stopRequested ) break;		 if(seconds && bytesRead > totalBytesRequested) break; } recordingNow = 0; doneRecording = 1; // Reset the card ioctl( dsp, SNDCTL_DSP_RESET, 0); close( dsp ); pthread_join( encodeThread, NULL );  //Do NOT exit until output is written while(shipToEncoder(NULL)) ; cerr << endl << "Total Bytes Recorded before encoding: " << bytesRead << endl; while(shipToEncoder(NULL)) ; if(!mpegrec) close(outputFd); else pclose( lame_encoder ); return 0;}

⌨️ 快捷键说明

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