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

📄 beaudio.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 4 页
字号:
{
	// This function is called by the BMediaRecorder object whenever it has a buffer
	// with recorded data ready.
	DETECTVARS(buffer, size/2)
	DETECTSOUND();

	((CircularBuffer *)cookie)->Fill((const BYTE **)&buffer, &size);
}

////////////////////////////////////////////////////////////////////////////////
// PSoundChannelBeOS

// This defines the number of times we would like to be called per second
// to play/record data
#define PLAYRECFREQ 20 

// Macro to let the default buffer size correspond neatly with the
// setting we put into the format.
#define DEFAULT_BUFSIZE(channels, rate, bits) 480
//((channels*rate*(bits/8))/PLAYRECFREQ)

PSoundChannelBeOS::PSoundChannelBeOS() :
	mRecorder(NULL),
	mPlayer(NULL),
	mBuffer(NULL),
	mNumBuffers(1),
	mResampler(NULL)
{
	PRINT(("default constructor"));

	InternalSetBuffers(DEFAULT_BUFSIZE(1, 8000, 16),DEFAULT_BUFSIZE(1, 8000, 16)/2);
	SetFormat(1, 8000, 16);
	
	// Nothing else to do here. Notice that the channel is not open for
	// playing/recording yet.
}


PSoundChannelBeOS::PSoundChannelBeOS(const PString & dev,
                             Directions dir,
                             unsigned numChannels,
                             unsigned sampleRate,
                             unsigned bitsPerSample) :
	mRecorder(NULL),
	mPlayer(NULL),
	mBuffer(NULL),
	mNumBuffers(1),
	mResampler(NULL)
{
	PRINT(("constructor %s %u %u %u", dir==Player ? "Player" : "Recorder", numChannels, sampleRate, bitsPerSample));
	
	InternalSetBuffers(DEFAULT_BUFSIZE(numChannels, sampleRate, bitsPerSample), DEFAULT_BUFSIZE(numChannels, sampleRate, bitsPerSample)/2);
	Open(dev, dir, numChannels, sampleRate, bitsPerSample);
	// ignore result; user will need to find out whether this succeeds using IsOpen
}


PSoundChannelBeOS::~PSoundChannelBeOS()
{
	PRINT((""));
	
	Close(); // destroys player and recorder
	InternalSetBuffers(0,0); // destroys buffer
}

static const PStringArray GetRecorderDevicesList(BMediaRecorder *Recorder)
{
	// Array to hold the list.
	PStringArray devlist;
    BMediaRecorder* bRecorder = NULL;
    
    if(Recorder != NULL)
      bRecorder = Recorder;

#ifdef MEDIA_KIT_UPDATE
    BMediaRecorder localRecorder("GetRecorderDevicesList");    
	bool result=true;
	status_t status;
	
	{
		if(bRecorder == NULL)
		{
			bRecorder = &localRecorder;
		}
	
		if (bRecorder == NULL || bRecorder->InitCheck()!=B_OK)
		{
			PRINT(("Error constructing recorder to fetch device names"));
			result=false;
		}
	}
	
	if (result)
	{
		media_format format;
		format.type = B_MEDIA_RAW_AUDIO;
		format.u.raw_audio=media_raw_audio_format::wildcard;
		
		// The resampler can only handle 16-bit audio
		format.u.raw_audio.format=media_raw_audio_format::B_AUDIO_SHORT;

		// Let the media recorder determine which sources are available		
		if ((status = bRecorder->FetchSources(format, false))!=B_OK)
		{
			PRINT(("Couldn't fetch BMediaRecorder sources; status=%d", status));
			result=false;
		}
	}
	
	if (result)
	{
		// Fetch the names of all output devices
		media_format format;
		BString outname;
		for (int i=0; i< bRecorder->CountSources(); i++)
		{
			if ((status = bRecorder->GetSourceAt(i, &outname, &format))==B_OK)
			{
				PRINT(("Device found: %s", outname.String()));
				devlist[i] = PString(outname.String());
			}
			else
			{
				PRINT(("error %d retrieving data for device %d", status, i));
				result=false;
			}
		}
	}

	if (!result)
	{
		devlist.RemoveAll();
	}
	
	return devlist;
#else
    // Media Kit is the only device
    devlist[0] = "MediaKit";
	return devlist;
#endif
}

PStringArray PSoundChannelBeOS::GetDeviceNames(Directions dir)
{
	if (dir==Recorder)
	{
		return GetRecorderDevicesList(NULL);
	}
	else
	{
		// not supported yet
		return PStringArray("MediaKit");
	}
}

PString PSoundChannelBeOS::GetDefaultDevice(Directions dir)
{
	if (dir==Recorder)
	{
		const PStringArray &devlist = GetRecorderDevicesList(NULL);
		
		if (devlist.GetSize()!=0)
		{
			return devlist[0];
		}
		else
		{
			return PString("MediaKit");
		}
	}
	else
	{
		// not supported yet
		return PString("MediaKit");
	}
}

BOOL PSoundChannelBeOS::OpenPlayer(void)
{
	// We're using cascaded "if result"s here for clarity
	BOOL result = TRUE;

#ifdef FILEDUMP
	media_format format;
	format.type=B_MEDIA_RAW_AUDIO;
	memcpy(&format.u.raw_audio, &mFormat, sizeof(mFormat));
			
	delete playwriter;
	playwriter=new BAudioFileWriter("play.wav", format, 441000);
#endif			
	
	// Must have a buffer
	if (!mBuffer)
	{
		result = FALSE;
		PRINT(("Trying to open as player without setting buffers first"));
	}
	
	if (result)		
	{
		// Create the player
		//was: mPlayer=new BSoundPlayer(&mFormat, NULL, PlayBuffer, NULL, mBuffer);
	
		mPlayer = new BSoundPlayer(
				&mFormat, 
				NULL,
				PlayBuffer,
				NULL,
				mBuffer);
				
		if ((mPlayer == NULL) || (mPlayer->InitCheck() != B_OK))
		{
			result = FALSE;
			PRINT(("Couldn't construct player"));
		}
	}
	
	if (result)
	{
		// Start the player
		if (mPlayer->Start() != B_OK)
		{
			result = FALSE;
			PRINT(("Couldn't start the player"));
		}
	}
	
	if (result)
	{
		// Enable the fetching of data by PlayBuffer
		mPlayer->SetHasData(true);
	}

	PRINT(("Returning %s", result?"success":"failure"));
	return result;
}

BOOL PSoundChannelBeOS::OpenRecorder(const PString &dev)
{
	// We're using cascaded "if result"s here for clarity
	BOOL result=TRUE;

	{
		if (!mBuffer)
		{
			result=FALSE;
			PRINT(("Trying to open as recorder without setting buffers first"));
		}
	}
	
	if (result)			
	{
		// Create the recorder
		mRecorder=new BMediaRecorder("PWLIB PSoundChannel recorder");
	
		if ((mRecorder==NULL) || (mRecorder->InitCheck()!=B_OK))
		{
			result=FALSE;
			PRINT(("Couldn't construct recorder"));
		}
	}

#ifdef MEDIA_KIT_UPDATE
	int32 sourceindex;
	if (result)
	{
		// Find the specified device in the list of input devices
		PINDEX x=GetRecorderDevicesList(mRecorder).GetStringsIndex(dev);
		if (x==P_MAX_INDEX)
		{
			result=FALSE;
			PRINT(("Couldn't find device %s in the list",(const char *)dev));
		}
		else
		{
			sourceindex=(int32)x;
		}
	}
	
#ifdef _DEBUG	
	if (result)
	{
		// Get information for the device
		BString outname;
		media_format xformat;
		status_t err;

		if ((err=mRecorder->GetSourceAt(sourceindex, &outname, &xformat))==B_OK)
		{
			PRINT(("%s", outname.String()));
			PRINT(("    type %d", (int)xformat.type));
			PRINT(("    AudioFormat 0x%X", (int)xformat.AudioFormat()));
			PRINT(("    u.raw_audio:"));
			PRINT(("        frame_rate: %f", xformat.u.raw_audio.frame_rate));
			PRINT(("        channel_count: %d", xformat.u.raw_audio.channel_count));
			PRINT(("        byte_order: %d", xformat.u.raw_audio.byte_order));
			PRINT(("        buffer_size: %d", xformat.u.raw_audio.buffer_size));
		}
		else
		{
			result=FALSE;
			PRINT(("couldn't get details for source %d: err=0x%X",sourceindex,err));
		}
	}
#endif

	if (result)
	{
		// Try to connect to the source
		if (mRecorder->ConnectSourceAt(sourceindex)!=B_OK)
		{
			result=FALSE;
			PRINT(("Couldn't connect BMediaRecorder to source"));
		}
	}

#else
	if (result)
	{
		// Connect the recorder to the default input device
		media_format format;
		format.type=B_MEDIA_RAW_AUDIO;
		format.u.raw_audio=media_raw_audio_format::wildcard;
		// The resampler can only handle 16-bit audio
		format.u.raw_audio.format=media_raw_audio_format::B_AUDIO_SHORT;
		if (mRecorder->Connect(format,0)!=B_OK)
		{
			result=FALSE;
			PRINT(("couldn't connect the recorder to the default source"));
		}
	}
#endif

	if (result)
	{
		// Create resampler
		media_format format=mRecorder->Format();

		delete mResampler;
		mResampler=new Resampler(
			format.u.raw_audio.frame_rate,
			mFormat.frame_rate,
			format.u.raw_audio.channel_count,
			mFormat.channel_count,
			0,
			2);

#ifdef FILEDUMP
		{
			media_format format;
			format.type=B_MEDIA_RAW_AUDIO;
			memcpy(&format.u.raw_audio, &mFormat, sizeof(mFormat));
			
			delete recwriter;
			recwriter=new BAudioFileWriter("record.wav", format);
		}
#endif

		// If the current buffer is not a resamplin buffer, re-create it 
		ResamplingBuffer *buf=dynamic_cast<ResamplingBuffer*>(mBuffer);
		
		if (buf==NULL)
		{
			PRINT(("re-creating buffer"));
			
			CircularBuffer *old=mBuffer;
			mBuffer=new ResamplingBuffer(mResampler, old);
			delete old;
		}
		else
		{
			buf->SetResampler(mResampler);
		}
	}
	
	if (result)
	{
		// Set the hook function to our data processing function
		PRINT(("Setting buffer hook, cookie=%p",mBuffer));
		if (mRecorder->SetBufferHook(RecordBuffer, mBuffer)!=B_OK)
		{
			result=FALSE;
			PRINT(("Couldn't set buffer hook on BMediaRecorder"));
		}
	}

	// If something went wrong, delete the recorder.
	if (!result)
	{
		if (mRecorder)
		{
			delete mRecorder;
			mRecorder=NULL;
		}
	}
	
	return result;		
}

BOOL PSoundChannelBeOS::Open(const PString & dev,
                         Directions dir,
                         unsigned numChannels,
                         unsigned sampleRate,
                         unsigned bitsPerSample)
{
	// We're using cascaded "if result"s here for clarity
	BOOL result = TRUE;
	PRINT(("%s %u %u %u", dir==Player?"Player":"Recorder", numChannels, sampleRate, bitsPerSample));
	
	// Close the channel first, just in case	
        Close();

	// Initialize the format struct, necessary to create player or recorder	
	if (!SetFormat(numChannels, sampleRate, bitsPerSample))
	{
	  result = FALSE;
	  PRINT(("Couldn't set format"));
	}

	if (result)
	{
		switch (dir)
		{
		case Player:
		        PRINT(("... trying to open player"));
                 	result=OpenPlayer();
			break;
			
		case Recorder:
                        PRINT(("...trying to open recorder"));
			result=OpenRecorder(dev);
			break;

		default:
			PRINT(("Unknown direction parameter"));
			result=FALSE;
		}
	}

	if (!result)
	{
		// If anything went wrong, clean up
		PRINT(("... can't open, cleaning up"));
                Close();
	}

        ::snooze(1*1000*1000);
	
        PRINT(("Returning %s", result?"success":"failure"));
   	return result;
}

BOOL PSoundChannelBeOS::Abort()
{
	return FALSE;
}


BOOL PSoundChannelBeOS::SetFormat(unsigned numChannels,
                              unsigned sampleRate,
                              unsigned bitsPerSample)
{
	PRINT(("%u %u %u", numChannels, sampleRate, bitsPerSample));
	
	// NOTE: all constructors should call this to initialize
	// the local members
	// Do NOT call the function with any parameter set to 0!
	
	// The function only fails if the channel is open.
	// This is because the player or recorder needs to be re-created when the
	// format changes.
	if (IsOpen())
	{
		PRINT(("Not allowed to set format on open channel"));
		return FALSE;
	}
	
	// Initialize the format struct
	// The numbers of bits that we support here are 8, 16 or 32 bits (signed),
	// results for other sizes are not defined.
	mFormat = media_raw_audio_format::wildcard;
	mFormat.frame_rate=(float)sampleRate;
	mFormat.channel_count=numChannels;
	mFormat.format=(bitsPerSample / 8) & 0xF; 
	mFormat.byte_order=B_HOST_IS_BENDIAN ? B_MEDIA_BIG_ENDIAN : B_MEDIA_LITTLE_ENDIAN;
	mFormat.buffer_size=DEFAULT_BUFSIZE(numChannels, sampleRate, bitsPerSample);

	return TRUE;
}


unsigned PSoundChannelBeOS::GetChannels() const
{
	return mFormat.channel_count;
}


unsigned PSoundChannelBeOS::GetSampleRate() const
{

⌨️ 快捷键说明

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