📄 qsa.cxx
字号:
return FALSE; } if (status.status == SND_PCM_STATUS_READY || status.status == SND_PCM_STATUS_UNDERRUN) { if (snd_pcm_plugin_prepare(entry->pcm_handle, snd_chnmode[direction]) < 0) { pthread_rwlock_unlock(&SoundHandleLock); return FALSE; } } if (written < 0) written = 0; } pthread_rwlock_unlock(&SoundHandleLock); return TRUE;}BOOL PSoundChannel::Read(void * buf, PINDEX len){ lastReadCount = 0; if (!Setup()) return FALSE; if (os_handle < 0) return FALSE; SoundHandleEntry * entry; pthread_rwlock_rdlock(&SoundHandleLock); for (entry = SoundHandleList; entry && entry->handle != os_handle; entry = entry->next); PTRACE(6, "QSA\tRead start"); lastReadCount = snd_pcm_plugin_read(entry->pcm_handle, buf, len); if (lastReadCount < len) { snd_pcm_channel_status_t status; memset(&status, 0, sizeof(status)); status.channel = SND_PCM_CHANNEL_CAPTURE; if (snd_pcm_plugin_status(entry->pcm_handle, &status) < 0) { pthread_rwlock_unlock(&SoundHandleLock); PTRACE(6, "QSA\tRead failed"); return FALSE; } if (status.status == SND_PCM_STATUS_READY || status.status == SND_PCM_STATUS_OVERRUN) { if (snd_pcm_plugin_prepare(entry->pcm_handle, SND_PCM_CHANNEL_CAPTURE) < 0) { pthread_rwlock_unlock(&SoundHandleLock); PTRACE(6, "QSA\tRead failed"); return FALSE; } } PTRACE(6, "QSA\tRead completed short - " << lastReadCount << " vs " << len); } else { PTRACE(6, "QSA\tRead completed"); } pthread_rwlock_unlock(&SoundHandleLock); return TRUE;}BOOL PSoundChannel::SetFormat(unsigned numChannels, unsigned sampleRate, unsigned bitsPerSample){ if (os_handle < 0) return SetErrorValues(NotOpen, EBADF); // check parameters PAssert((bitsPerSample == 8) || (bitsPerSample == 16), PInvalidParameter); PAssert(numChannels >= 1 && numChannels <= 2, PInvalidParameter); SoundHandleEntry * entry; pthread_rwlock_rdlock(&SoundHandleLock); for (entry = SoundHandleList; entry && entry->handle != os_handle; entry = entry->next); if (entry->isInitialised) { if ((numChannels != entry->numChannels) || (sampleRate != entry->sampleRate) || (bitsPerSample != entry->bitsPerSample)) { pthread_rwlock_unlock(&SoundHandleLock); PTRACE(6, "OSS\tTried to change read/write format without stopping"); return FALSE; } pthread_rwlock_unlock(&SoundHandleLock); return TRUE; } if (direction == Player) { snd_pcm_plugin_playback_drain(entry->pcm_handle); } entry->numChannels = numChannels; entry->sampleRate = sampleRate; entry->bitsPerSample = bitsPerSample; entry->isInitialised = FALSE; pthread_rwlock_unlock(&SoundHandleLock); // mark this channel as uninitialised isInitialised = FALSE; return TRUE;}// Get the number of channels (mono/stereo) in the sound.unsigned PSoundChannel::GetChannels() const{ return mNumChannels;}// Get the sample rate in samples per second.unsigned PSoundChannel::GetSampleRate() const{ return actualSampleRate;}// Get the sample size in bits per sample.unsigned PSoundChannel::GetSampleSize() const{ return mBitsPerSample;}BOOL PSoundChannel::SetBuffers(PINDEX size, PINDEX count){ if (os_handle < 0) return SetErrorValues(NotOpen, EBADF); //PINDEX totalSize = size * count; //size = 16; //count = (totalSize + 15) / 16; PAssert(size > 0 && count > 0 && count < 65536, PInvalidParameter); int arg = 1; while (size > (PINDEX)(1 << arg)) arg++; arg |= count << 16; SoundHandleEntry * entry; pthread_rwlock_rdlock(&SoundHandleLock); for (entry = SoundHandleList; entry && entry->handle != os_handle; entry = entry->next); if (entry->isInitialised) { if (entry->fragmentValue != (unsigned)arg) { pthread_rwlock_unlock(&SoundHandleLock); PTRACE(6, "OSS\tTried to change buffers without stopping"); return FALSE; } pthread_rwlock_unlock(&SoundHandleLock); return TRUE; } if (direction == Player) { snd_pcm_plugin_playback_drain(entry->pcm_handle); } // set information in the common record entry->fragmentValue = arg; entry->isInitialised = FALSE; pthread_rwlock_unlock(&SoundHandleLock); // flag this channel as not initialised isInitialised = FALSE; return TRUE;}BOOL PSoundChannel::GetBuffers(PINDEX & size, PINDEX & count){ if (os_handle < 0) return SetErrorValues(NotOpen, EBADF); SoundHandleEntry * entry; pthread_rwlock_rdlock(&SoundHandleLock); for (entry = SoundHandleList; entry && entry->handle != os_handle; entry = entry->next); int arg = entry->fragmentValue; count = arg >> 16; size = 1 << (arg&0xffff); pthread_rwlock_unlock(&SoundHandleLock); return TRUE;}BOOL PSoundChannel::PlaySound(const PSound & sound, BOOL wait){ if (os_handle < 0) return SetErrorValues(NotOpen, EBADF); 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) return SetErrorValues(NotOpen, EBADF); 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) return SetErrorValues(NotOpen, EBADF); SoundHandleEntry * entry; pthread_rwlock_rdlock(&SoundHandleLock); for (entry = SoundHandleList; entry && entry->handle != os_handle; entry = entry->next); snd_pcm_channel_status_t status; memset(&status, 0, sizeof(status)); status.channel = snd_chnmode[direction]; if (snd_pcm_plugin_status(entry->pcm_handle, &status) < 0) { pthread_rwlock_unlock(&SoundHandleLock); return FALSE; } int ret = (abs(status.free) / (entry->bitsPerSample / 8)); pthread_rwlock_unlock(&SoundHandleLock); return ret;}BOOL PSoundChannel::WaitForPlayCompletion(){ if (os_handle < 0) return SetErrorValues(NotOpen, EBADF); SoundHandleEntry * entry; pthread_rwlock_rdlock(&SoundHandleLock); for (entry = SoundHandleList; entry && entry->handle != os_handle; entry = entry->next); if (snd_pcm_playback_flush(entry->pcm_handle) < 0) { pthread_rwlock_unlock(&SoundHandleLock); return FALSE; } pthread_rwlock_unlock(&SoundHandleLock); return TRUE;}BOOL PSoundChannel::RecordSound(PSound & sound){ if (os_handle < 0) return SetErrorValues(NotOpen, EBADF); return FALSE;}BOOL PSoundChannel::RecordFile(const PFilePath & filename){ if (os_handle < 0) return SetErrorValues(NotOpen, EBADF); return FALSE;}BOOL PSoundChannel::StartRecording(){ if (os_handle < 0) return SetErrorValues(NotOpen, EBADF); int fd = os_handle; fd_set fds; FD_ZERO(&fds); FD_SET(fd, &fds); struct timeval instant = {0, 0}; return ConvertOSError(::select(fd + 1, &fds, NULL, NULL, &instant));}BOOL PSoundChannel::IsRecordBufferFull(){ if (os_handle < 0) return SetErrorValues(NotOpen, EBADF); PTRACE(1, "IsRecordBufferFull()\n"); /* do I suppose to get the status, and check sth ? */ return TRUE;}BOOL PSoundChannel::AreAllRecordBuffersFull(){ if (os_handle < 0) return SetErrorValues(NotOpen, EBADF); PTRACE(1, "AreAllRecordBuffersFull()\n"); /* do I suppose to get the status, and check sth ? */ return TRUE;}BOOL PSoundChannel::WaitForRecordBufferFull(){ if (os_handle < 0) return SetErrorValues(NotOpen, EBADF); PTRACE(1, "WaitForRecordBufferFull()\n"); return PXSetIOBlock(PXReadBlock, readTimeout);}BOOL PSoundChannel::WaitForAllRecordBuffersFull(){ PTRACE(1, "WaitForAllRecordBuffersFull()\n"); return FALSE;}BOOL PSoundChannel::Abort(){ if (direction == Player && os_handle != -1) { SoundHandleEntry * entry; pthread_rwlock_rdlock(&SoundHandleLock); for (entry = SoundHandleList; entry && entry->handle != os_handle; entry = entry->next); snd_pcm_plugin_playback_drain(entry->pcm_handle); pthread_rwlock_unlock(&SoundHandleLock); } return TRUE;}BOOL PSoundChannel::SetVolume(unsigned newVal){ if (os_handle < 0) { return FALSE; } SoundHandleEntry *entry; pthread_rwlock_rdlock(&SoundHandleLock); for (entry = SoundHandleList; entry && entry->handle != os_handle; entry = entry->next); int ret; if ((ret = snd_mixer_group_read(entry->mixer_handle, &entry->group)) < 0) { pthread_rwlock_unlock(&SoundHandleLock); cerr << "snd_mixer_group_read: " << strerror(-ret) << endl; return FALSE; } /* QSA treat the newVal as a percentage */ newVal = (newVal * (entry->group.max - entry->group.min) / 100) + entry->group.min; entry->group.volume.names.front_left = newVal; entry->group.volume.names.front_right = newVal; if ((ret = snd_mixer_group_write(entry->mixer_handle, &entry->group)) < 0) { pthread_rwlock_unlock(&SoundHandleLock); cerr << "snd_mixer_group_write: " << strerror(-ret) << endl; return FALSE; } pthread_rwlock_unlock(&SoundHandleLock); return TRUE;}BOOL PSoundChannel::GetVolume(unsigned &devVol){ if (os_handle == 0) { return FALSE; } SoundHandleEntry *entry; pthread_rwlock_rdlock(&SoundHandleLock); for (entry = SoundHandleList; entry && entry->handle != os_handle; entry = entry->next); int ret; if ((ret = snd_mixer_group_read(entry->mixer_handle, &entry->group)) < 0) { pthread_rwlock_unlock(&SoundHandleLock); return FALSE; } pthread_rwlock_unlock(&SoundHandleLock); /* return the percentage */ devVol = (unsigned)(entry->group.volume.names.front_left - entry->group.min) * 100 / (entry->group.max - entry->group.min); return TRUE;} // End of file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -