📄 ossaix.cxx
字号:
dictMutex.Signal();
return stat;
}
BOOL PSoundChannel::Close()
{
// if the channel isn't open, do nothing
if (os_handle < 0)
return TRUE;
if (os_handle == 0) {
os_handle = -1;
return TRUE;
}
// the device must be in the dictionary
dictMutex.Wait();
SoundHandleEntry * entry;
PAssert((entry = handleDict().GetAt(device)) != NULL, "Unknown sound device \"" + device + "\" found");
// modify the directions bit mask in the dictionary
entry->direction ^= (direction+1);
// if this is the last usage of this entry, then remove it
if (entry->direction == 0) {
handleDict().RemoveAt(device);
dictMutex.Signal();
return PChannel::Close();
}
// flag this channel as closed
dictMutex.Signal();
os_handle = -1;
return TRUE;
}
BOOL PSoundChannel::Write(const void * buf, PINDEX len)
{
if (!Setup())
return FALSE;
if (os_handle > 0) {
while (!ConvertOSError(::write(os_handle, (void *)buf, len)))
if (GetErrorCode() != Interrupted)
return FALSE;
return TRUE;
}
int index = 0;
while (len > 0) {
len--;
buffer[endptr++] = ((char *)buf)[index++];
if (endptr == LOOPBACK_BUFFER_SIZE)
endptr = 0;
while (((startptr - 1) == endptr) || ((endptr==LOOPBACK_BUFFER_SIZE - 1) && (startptr==0))) {
usleep(5000);
}
}
return TRUE;
}
BOOL PSoundChannel::Read(void * buf, PINDEX len)
{
if (!Setup())
return FALSE;
if (os_handle > 0) {
while (!ConvertOSError(::read(os_handle, (void *)buf, len)))
if (GetErrorCode() != Interrupted)
return FALSE;
return TRUE;
}
int index = 0;
while (len > 0) {
while (startptr == endptr)
usleep(5000);
len--;
((char *)buf)[index++]=buffer[startptr++];
if (startptr == LOOPBACK_BUFFER_SIZE)
startptr = 0;
}
return TRUE;
}
BOOL PSoundChannel::SetFormat(unsigned numChannels,
unsigned sampleRate,
unsigned bitsPerSample)
{
if (os_handle < 0) {
lastError = NotOpen;
return FALSE;
}
// check parameters
PAssert((bitsPerSample == 8) || (bitsPerSample == 16), PInvalidParameter);
PAssert(numChannels >= 1 && numChannels <= 2, PInvalidParameter);
Abort();
// lock the dictionary
dictMutex.Wait();
// the device must always be in the dictionary
PAssertOS(handleDict().Contains(device));
// get record for the device
SoundHandleEntry & entry = handleDict()[device];
entry.numChannels = numChannels;
entry.sampleRate = sampleRate;
entry.bitsPerSample = bitsPerSample;
entry.isInitialised = FALSE;
// unlock dictionary
dictMutex.Signal();
// mark this channel as uninitialised
isInitialised = FALSE;
return TRUE;
}
BOOL PSoundChannel::SetBuffers(PINDEX size, PINDEX count)
{
if (os_handle < 0) {
lastError = NotOpen;
return FALSE;
}
Abort();
PAssert(size > 0 && count > 0 && count < 65536, PInvalidParameter);
int arg = 1;
while (size > (PINDEX)(1 << arg))
arg++;
arg |= count << 16;
// lock the dictionary
dictMutex.Wait();
// the device must always be in the dictionary
PAssertOS(handleDict().Contains(device));
// get record for the device
SoundHandleEntry & entry = handleDict()[device];
// set information in the common record
entry.fragmentValue = arg;
entry.isInitialised = FALSE;
// flag this channel as not initialised
isInitialised = FALSE;
dictMutex.Signal();
return TRUE;
}
BOOL PSoundChannel::GetBuffers(PINDEX & size, PINDEX & count)
{
if (os_handle < 0) {
lastError = NotOpen;
return FALSE;
}
// lock the dictionary
dictMutex.Wait();
// the device must always be in the dictionary
PAssertOS(handleDict().Contains(device));
SoundHandleEntry & entry = handleDict()[device];
int arg = entry.fragmentValue;
dictMutex.Signal();
count = arg >> 16;
size = 1 << (arg&0xffff);
return TRUE;
}
BOOL PSoundChannel::PlaySound(const PSound & sound, BOOL wait)
{
if (os_handle < 0) {
lastError = NotOpen;
return FALSE;
}
Abort();
if (!Write((const BYTE *)sound, sound.GetSize()))
return FALSE;
if (wait)
return WaitForPlayCompletion();
return TRUE;
}
BOOL PSoundChannel::PlayFile(const PFilePath & filename, BOOL wait)
{
if (os_handle < 0) {
lastError = NotOpen;
return FALSE;
}
PFile file(filename, PFile::ReadOnly);
if (!file.IsOpen())
return FALSE;
for (;;) {
BYTE buffer[256];
if (!file.Read(buffer, 256))
break;
PINDEX len = file.GetLastReadCount();
if (len == 0)
break;
if (!Write(buffer, len))
break;
}
file.Close();
if (wait)
return WaitForPlayCompletion();
return TRUE;
}
BOOL PSoundChannel::HasPlayCompleted()
{
if (os_handle < 0) {
lastError = NotOpen;
return FALSE;
}
if (os_handle == 0)
return BYTESINBUF <= 0;
#ifndef P_AIX
audio_buf_info info;
if (!ConvertOSError(::ioctl(os_handle, SNDCTL_DSP_GETOSPACE, &info)))
return FALSE;
return info.fragments == info.fragstotal;
#else
return 0;
#endif
}
BOOL PSoundChannel::WaitForPlayCompletion()
{
if (os_handle < 0) {
lastError = NotOpen;
return FALSE;
}
if (os_handle == 0) {
while (BYTESINBUF > 0)
usleep(1000);
return TRUE;
}
#ifndef P_AIX
return ConvertOSError(::ioctl(os_handle, SNDCTL_DSP_SYNC, NULL));
#else
return 0;
#endif
}
BOOL PSoundChannel::RecordSound(PSound & sound)
{
if (os_handle < 0) {
lastError = NotOpen;
return FALSE;
}
return FALSE;
}
BOOL PSoundChannel::RecordFile(const PFilePath & filename)
{
if (os_handle < 0) {
lastError = NotOpen;
return FALSE;
}
return FALSE;
}
BOOL PSoundChannel::StartRecording()
{
if (os_handle < 0) {
lastError = NotOpen;
return FALSE;
}
if (os_handle == 0)
return TRUE;
fd_set fds;
FD_ZERO(&fds);
FD_SET(os_handle, &fds);
struct timeval timeout;
memset(&timeout, 0, sizeof(timeout));
return ConvertOSError(::select(1, &fds, NULL, NULL, &timeout));
}
BOOL PSoundChannel::IsRecordBufferFull()
{
if (os_handle < 0) {
lastError = NotOpen;
return FALSE;
}
if (os_handle == 0)
return (BYTESINBUF > 0);
#ifndef P_AIX
audio_buf_info info;
if (!ConvertOSError(::ioctl(os_handle, SNDCTL_DSP_GETISPACE, &info)))
return FALSE;
return info.fragments > 0;
#else
return 0;
#endif
}
BOOL PSoundChannel::AreAllRecordBuffersFull()
{
if (os_handle < 0) {
lastError = NotOpen;
return FALSE;
}
if (os_handle == 0)
return (BYTESINBUF == LOOPBACK_BUFFER_SIZE);
#ifndef P_AIX
audio_buf_info info;
if (!ConvertOSError(::ioctl(os_handle, SNDCTL_DSP_GETISPACE, &info)))
return FALSE;
return info.fragments == info.fragstotal;
#else
return 0;
#endif
}
BOOL PSoundChannel::WaitForRecordBufferFull()
{
if (os_handle < 0) {
lastError = NotOpen;
return FALSE;
}
return PXSetIOBlock(PXReadBlock, readTimeout);
}
BOOL PSoundChannel::WaitForAllRecordBuffersFull()
{
return FALSE;
}
BOOL PSoundChannel::Abort()
{
if (os_handle == 0) {
startptr = endptr = 0;
return TRUE;
}
#ifndef P_AIX
return ConvertOSError(ioctl(os_handle, SNDCTL_DSP_RESET, NULL));
#else
return 0;
#endif
}
BOOL PSoundChannel::SetVolume(unsigned newVolume)
{
cerr << __FILE__ << "PSoundChannel :: SetVolume called in error. Please fix"<<endl;
return FALSE;
}
BOOL PSoundChannel::GetVolume(unsigned & volume)
{
cerr << __FILE__ << "PSoundChannel :: GetVolume called in error. Please fix"<<endl;
return FALSE;
}
// End of file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -