Victory! With these changes, playback is nearly perfect under BeOS (tested with
C-Media based sound card). In Haiku, I could test with HD Audio, and playback has clicks. It doesn't seem to have to do with the "drift", which is now correctly published, I am not sure what exactly is causing it, I would like to test on different hardware yet. * I have modified the buffering policy (4 will give about 2048 bytes internal OSS buffer), which decreases the latency of the node to an acceptable value. * I completely replaced the timesource publishing algo to be more reliable. * Removed now unnecessary methods from OpenSoundDeviceEngine. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26059 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "OpenSoundDeviceEngine.h"
|
#include "OpenSoundDeviceEngine.h"
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "driver_io.h"
|
#include "driver_io.h"
|
||||||
#include <MediaDefs.h>
|
#include <MediaDefs.h>
|
||||||
@@ -13,6 +14,8 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "SupportFunctions.h"
|
||||||
|
|
||||||
OpenSoundDeviceEngine::~OpenSoundDeviceEngine()
|
OpenSoundDeviceEngine::~OpenSoundDeviceEngine()
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
@@ -27,8 +30,7 @@ OpenSoundDeviceEngine::OpenSoundDeviceEngine(oss_audioinfo *info)
|
|||||||
, fOpenMode(0)
|
, fOpenMode(0)
|
||||||
, fFD(-1)
|
, fFD(-1)
|
||||||
, fMediaFormat()
|
, fMediaFormat()
|
||||||
, fPlayedFramesCount(0LL)
|
, fDriverBufferSize(0)
|
||||||
, fPlayedRealTime(0LL)
|
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
fInitCheckStatus = B_NO_INIT;
|
fInitCheckStatus = B_NO_INIT;
|
||||||
@@ -93,7 +95,19 @@ status_t OpenSoundDeviceEngine::Open(int mode)
|
|||||||
Close();
|
Close();
|
||||||
return EIO;
|
return EIO;
|
||||||
}
|
}
|
||||||
#if 1
|
|
||||||
|
// set latency policy = fragment size (4 means 2048 bytes driver buffer
|
||||||
|
// in my tests)
|
||||||
|
// XXX: BParameter?
|
||||||
|
v = 4;
|
||||||
|
if (ioctl(fFD, SNDCTL_DSP_POLICY, &v, sizeof(int)) < 0) {
|
||||||
|
if (errno != EIO && errno != EINVAL) {
|
||||||
|
fInitCheckStatus = errno;
|
||||||
|
Close();
|
||||||
|
return EIO;
|
||||||
|
}
|
||||||
|
// TODO: use this older API as fallback:
|
||||||
|
#if 0
|
||||||
// set fragments
|
// set fragments
|
||||||
v = 0x7fff0000 | 0x000b; // unlimited * 2048
|
v = 0x7fff0000 | 0x000b; // unlimited * 2048
|
||||||
if (ioctl(fFD, SNDCTL_DSP_SETFRAGMENT, &v, sizeof(int)) < 0) {
|
if (ioctl(fFD, SNDCTL_DSP_SETFRAGMENT, &v, sizeof(int)) < 0) {
|
||||||
@@ -102,20 +116,10 @@ status_t OpenSoundDeviceEngine::Open(int mode)
|
|||||||
return EIO;
|
return EIO;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
|
||||||
// set latency policy = fragment size
|
|
||||||
// XXX: BParameter?
|
|
||||||
v = 0;
|
|
||||||
if (ioctl(fFD, SNDCTL_DSP_POLICY, &v, sizeof(int)) < 0) {
|
|
||||||
fInitCheckStatus = errno;
|
|
||||||
Close();
|
|
||||||
return EIO;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
fPlayedFramesCount = 0LL;
|
fDriverBufferSize = 2048;
|
||||||
fPlayedRealTime = system_time();
|
// preliminary, adjusted in AcceptFormat()
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,8 +132,6 @@ status_t OpenSoundDeviceEngine::Close(void)
|
|||||||
fFD = -1;
|
fFD = -1;
|
||||||
fOpenMode = 0;
|
fOpenMode = 0;
|
||||||
fMediaFormat = media_format();
|
fMediaFormat = media_format();
|
||||||
fPlayedFramesCount = 0LL;
|
|
||||||
fPlayedRealTime = 0LL;
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,50 +147,32 @@ ssize_t OpenSoundDeviceEngine::Read(void *buffer, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ssize_t OpenSoundDeviceEngine::Write(const void *buffer, size_t size)
|
ssize_t
|
||||||
|
OpenSoundDeviceEngine::Write(const void *buffer, size_t size)
|
||||||
{
|
{
|
||||||
ssize_t done;
|
|
||||||
int v;
|
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
ASSERT(size > 0);
|
ASSERT(size > 0);
|
||||||
done = write(fFD, buffer, size);
|
|
||||||
|
ssize_t done = write(fFD, buffer, size);
|
||||||
if (done < 0)
|
if (done < 0)
|
||||||
return errno;
|
return errno;
|
||||||
switch (fMediaFormat.type) {
|
|
||||||
case B_MEDIA_RAW_AUDIO:
|
|
||||||
fPlayedFramesCount += done / (fMediaFormat.u.raw_audio.channel_count
|
|
||||||
* (fMediaFormat.AudioFormat() & media_raw_audio_format::B_AUDIO_SIZE_MASK));
|
|
||||||
/* fPlayedRealTime = system_time();
|
|
||||||
v = 0;
|
|
||||||
if (ioctl(fFD, SNDCTL_DSP_GETODELAY, &v, sizeof(int)) > -1) {
|
|
||||||
bigtime_t delay = (bigtime_t)v * 1000000LL
|
|
||||||
/ (fMediaFormat.u.raw_audio.channel_count * fMediaFormat.u.raw_audio.frame_rate
|
|
||||||
* (fMediaFormat.AudioFormat() & media_raw_audio_format::B_AUDIO_SIZE_MASK));
|
|
||||||
fPlayedRealTime += delay;
|
|
||||||
PRINT(("********************************* v = %d, delay %Ld\n", v, delay));
|
|
||||||
}*/
|
|
||||||
// PRINT(("OpenSoundDeviceEngine::%s: wrote %d, played %Ld frames"/*", realtime %Ld"*/"\n", __FUNCTION__, done, fPlayedFramesCount/*, fPlayedRealTime*/));
|
|
||||||
break;
|
|
||||||
case B_MEDIA_ENCODED_AUDIO:
|
|
||||||
//XXX: WRITEME! -- bitrate ?
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
return done;
|
return done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t OpenSoundDeviceEngine::UpdateInfo(void)
|
status_t
|
||||||
|
OpenSoundDeviceEngine::UpdateInfo()
|
||||||
{
|
{
|
||||||
status_t err;
|
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
if (fFD < 0)
|
if (fFD < 0)
|
||||||
return ENODEV;
|
return ENODEV;
|
||||||
|
|
||||||
if (ioctl(fFD, SNDCTL_ENGINEINFO, &fAudioInfo, sizeof(oss_audioinfo)) < 0) {
|
if (ioctl(fFD, SNDCTL_ENGINEINFO, &fAudioInfo, sizeof(oss_audioinfo)) < 0)
|
||||||
return errno;
|
return errno;
|
||||||
}
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,18 +180,15 @@ status_t OpenSoundDeviceEngine::UpdateInfo(void)
|
|||||||
bigtime_t
|
bigtime_t
|
||||||
OpenSoundDeviceEngine::PlaybackLatency()
|
OpenSoundDeviceEngine::PlaybackLatency()
|
||||||
{
|
{
|
||||||
bigtime_t latency;
|
bigtime_t latency = time_for_buffer(fDriverBufferSize, fMediaFormat);
|
||||||
int delay;
|
bigtime_t cardLatency = CardLatency();
|
||||||
delay = GetODelay();
|
if (cardLatency == 0) {
|
||||||
delay = 0; //XXX
|
// that's unrealistic, take matters into own hands
|
||||||
latency = (bigtime_t)((double)delay * 1000000LL
|
cardLatency = latency / 3;
|
||||||
/ (fMediaFormat.u.raw_audio.channel_count
|
}
|
||||||
* fMediaFormat.u.raw_audio.frame_rate
|
latency += cardLatency;
|
||||||
* (fMediaFormat.AudioFormat()
|
// PRINT(("PlaybackLatency: odelay %d latency %Ld card %Ld\n",
|
||||||
& media_raw_audio_format::B_AUDIO_SIZE_MASK)));
|
// fDriverBufferSize, latency, CardLatency()));
|
||||||
PRINT(("PlaybackLatency: odelay %d latency %Ld card %Ld\n", delay, latency,
|
|
||||||
CardLatency()));
|
|
||||||
latency += CardLatency();
|
|
||||||
return latency;
|
return latency;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,35 +346,42 @@ OpenSoundDeviceEngine::GetCurrentIPtr(int32 *fifoed, oss_count_t *info)
|
|||||||
|
|
||||||
|
|
||||||
int64
|
int64
|
||||||
OpenSoundDeviceEngine::GetCurrentOPtr(int32 *fifoed, oss_count_t *info)
|
OpenSoundDeviceEngine::GetCurrentOPtr(int32* fifoed, size_t* fragmentPos)
|
||||||
{
|
{
|
||||||
oss_count_t ocount;
|
|
||||||
count_info cinfo;
|
|
||||||
CALLED();
|
CALLED();
|
||||||
if (!info)
|
|
||||||
info = &ocount;
|
if (!(fOpenMode & OPEN_WRITE)) {
|
||||||
memset(info, 0, sizeof(oss_count_t));
|
if (fifoed != NULL)
|
||||||
if (!(fOpenMode & OPEN_WRITE))
|
*fifoed = 0;
|
||||||
return 0;
|
return 0;
|
||||||
if (ioctl(fFD, SNDCTL_DSP_CURRENT_OPTR, info, sizeof(oss_count_t)) < 0) {
|
}
|
||||||
|
|
||||||
|
oss_count_t info;
|
||||||
|
memset(&info, 0, sizeof(oss_count_t));
|
||||||
|
|
||||||
|
if (ioctl(fFD, SNDCTL_DSP_CURRENT_OPTR, &info, sizeof(oss_count_t)) < 0) {
|
||||||
PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n",
|
PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n",
|
||||||
__FUNCTION__, "SNDCTL_DSP_CURRENT_OPTR", strerror(errno)));
|
__FUNCTION__, "SNDCTL_DSP_CURRENT_OPTR", strerror(errno)));
|
||||||
//return EIO;
|
|
||||||
// fallback: try GET*PTR
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fragmentPos != NULL) {
|
||||||
|
count_info cinfo;
|
||||||
if (ioctl(fFD, SNDCTL_DSP_GETOPTR, &cinfo, sizeof(count_info)) < 0) {
|
if (ioctl(fFD, SNDCTL_DSP_GETOPTR, &cinfo, sizeof(count_info)) < 0) {
|
||||||
PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n",
|
PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n",
|
||||||
__FUNCTION__, "SNDCTL_DSP_GETOPTR", strerror(errno)));
|
__FUNCTION__, "SNDCTL_DSP_GETOPTR", strerror(errno)));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// it's probably wrong...
|
*fragmentPos = cinfo.ptr;
|
||||||
info->samples = cinfo.bytes / (fMediaFormat.u.raw_audio.channel_count
|
|
||||||
* (fMediaFormat.AudioFormat() & media_raw_audio_format::B_AUDIO_SIZE_MASK));
|
|
||||||
info->fifo_samples = 0;
|
|
||||||
}
|
}
|
||||||
//PRINT(("OpenSoundDeviceEngine::%s: OPTR: { samples=%Ld, fifo_samples=%d }\n", __FUNCTION__, info->samples, info->fifo_samples));
|
|
||||||
if (fifoed)
|
// PRINT(("OpenSoundDeviceEngine::%s: OPTR: { samples=%Ld, "
|
||||||
*fifoed = info->fifo_samples;
|
// "fifo_samples=%d }\n", __FUNCTION__, info->samples,
|
||||||
return info->samples;
|
// info->fifo_samples));
|
||||||
|
if (fifoed != NULL)
|
||||||
|
*fifoed = info.fifo_samples;
|
||||||
|
return info.samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -433,14 +421,10 @@ OpenSoundDeviceEngine::GetOUnderruns()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int OpenSoundDeviceEngine::GetODelay(void)
|
size_t
|
||||||
|
OpenSoundDeviceEngine::DriverBufferSize() const
|
||||||
{
|
{
|
||||||
//CALLED();
|
return fDriverBufferSize;
|
||||||
int v = 1;
|
|
||||||
if (ioctl(fFD, SNDCTL_DSP_GETODELAY, &v, sizeof(int)) < 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -464,43 +448,9 @@ status_t OpenSoundDeviceEngine::StartRecording(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int64 OpenSoundDeviceEngine::PlayedFramesCount(void)
|
status_t
|
||||||
{
|
OpenSoundDeviceEngine::WildcardFormatFor(int fmt, media_format &format,
|
||||||
int64 played;
|
bool rec)
|
||||||
int32 fifoed;
|
|
||||||
played = GetCurrentOPtr(&fifoed);
|
|
||||||
//played += fifoed;
|
|
||||||
//return played;
|
|
||||||
fPlayedFramesCount = played - fifoed;
|
|
||||||
return fPlayedFramesCount;//XXX
|
|
||||||
return fPlayedFramesCount - (GetODelay() / (fMediaFormat.u.raw_audio.channel_count
|
|
||||||
* (fMediaFormat.AudioFormat() & media_raw_audio_format::B_AUDIO_SIZE_MASK)));
|
|
||||||
return fPlayedFramesCount - (GetODelay() / (/*fMediaFormat.u.raw_audio.channel_count
|
|
||||||
* */(fMediaFormat.AudioFormat() & media_raw_audio_format::B_AUDIO_SIZE_MASK)));
|
|
||||||
//return fPlayedFramesCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bigtime_t OpenSoundDeviceEngine::PlayedRealTime(void)
|
|
||||||
{
|
|
||||||
//CALLED();
|
|
||||||
bigtime_t playedRealTime = system_time();
|
|
||||||
return playedRealTime;//XXX
|
|
||||||
int v = 1;
|
|
||||||
if (ioctl(fFD, SNDCTL_DSP_GETODELAY, &v, sizeof(int)) < 0) {
|
|
||||||
return playedRealTime;
|
|
||||||
}
|
|
||||||
bigtime_t delay = (bigtime_t)(v * 1000000LL
|
|
||||||
/ (fMediaFormat.u.raw_audio.channel_count * fMediaFormat.u.raw_audio.frame_rate
|
|
||||||
* (fMediaFormat.AudioFormat() & media_raw_audio_format::B_AUDIO_SIZE_MASK)));
|
|
||||||
playedRealTime += delay;
|
|
||||||
//PRINT(("********************************* v = %d, delay %Ld\n", v, delay));
|
|
||||||
// playedRealTime-=41000;
|
|
||||||
return playedRealTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t OpenSoundDeviceEngine::WildcardFormatFor(int fmt, media_format &format, bool rec)
|
|
||||||
{
|
{
|
||||||
status_t err;
|
status_t err;
|
||||||
CALLED();
|
CALLED();
|
||||||
@@ -638,32 +588,20 @@ status_t OpenSoundDeviceEngine::AcceptFormatFor(int fmt, media_format &format, b
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// retrieve the driver buffer size (it's important to do this
|
||||||
|
// after all the other setup, since OSS may have adjusted it, and
|
||||||
#if 0
|
// also weird things happen if this ioctl() is done before other
|
||||||
raw.buffer_size = DEFAULT_BUFFER_SIZE
|
// setup itctl()s)
|
||||||
* (raw.format & media_raw_audio_format::B_AUDIO_SIZE_MASK)
|
|
||||||
* raw.channel_count;
|
|
||||||
#endif
|
|
||||||
audio_buf_info abinfo;
|
audio_buf_info abinfo;
|
||||||
if (ioctl(fFD, rec?SNDCTL_DSP_GETISPACE:SNDCTL_DSP_GETOSPACE, &abinfo, sizeof(abinfo)) < 0) {
|
memset(&abinfo, 0, sizeof(audio_buf_info));
|
||||||
PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n",
|
if (ioctl(fFD, SNDCTL_DSP_GETOSPACE, &abinfo, sizeof(audio_buf_info)) < 0) {
|
||||||
__FUNCTION__, "SNDCTL_DSP_GET?SPACE", strerror(errno)));
|
fprintf(stderr, "failed to retrieve driver buffer size!\n");
|
||||||
return -1;
|
abinfo.bytes = 0;
|
||||||
}
|
}
|
||||||
PRINT(("OSS: %cSPACE: { bytes=%d, fragments=%d, fragsize=%d, fragstotal=%d }\n", rec?'I':'O', abinfo.bytes, abinfo.fragments, abinfo.fragsize, abinfo.fragstotal));
|
fDriverBufferSize = abinfo.bytes;
|
||||||
// cache the first one in the Device
|
|
||||||
// so StartThread() knows the number of frags
|
raw.buffer_size = fDriverBufferSize;
|
||||||
//if (!fFragments.fragstotal)
|
|
||||||
// memcpy(&fFragments, &abinfo, sizeof(abinfo));
|
|
||||||
|
|
||||||
// make sure buffer size is less than the driver's own buffer ( /2 to keep some margin )
|
|
||||||
// if (/*rec && raw.buffer_size &&*/ raw.buffer_size >= abinfo.fragsize * abinfo.fragstotal / 2)
|
|
||||||
// return B_MEDIA_BAD_FORMAT;
|
|
||||||
// if (!raw.buffer_size)
|
|
||||||
raw.buffer_size = abinfo.fragsize;// * abinfo.fragstotal / 4;//XXX
|
|
||||||
/* * (raw.format & media_raw_audio_format::B_AUDIO_SIZE_MASK)
|
|
||||||
* raw.channel_count;*/
|
|
||||||
} else if (format.type == B_MEDIA_ENCODED_AUDIO) {
|
} else if (format.type == B_MEDIA_ENCODED_AUDIO) {
|
||||||
media_raw_audio_format &raw = format.u.encoded_audio.output;
|
media_raw_audio_format &raw = format.u.encoded_audio.output;
|
||||||
// XXX: do we really have to do this ?
|
// XXX: do we really have to do this ?
|
||||||
@@ -680,6 +618,7 @@ status_t OpenSoundDeviceEngine::AcceptFormatFor(int fmt, media_format &format, b
|
|||||||
}
|
}
|
||||||
// cache it
|
// cache it
|
||||||
fMediaFormat = format;
|
fMediaFormat = format;
|
||||||
|
|
||||||
string_for_format(format, buf, 1024);
|
string_for_format(format, buf, 1024);
|
||||||
PRINT(("%s: %s\n", __FUNCTION__, buf));
|
PRINT(("%s: %s\n", __FUNCTION__, buf));
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -740,15 +679,16 @@ status_t OpenSoundDeviceEngine::SpecializeFormatFor(int fmt, media_format &forma
|
|||||||
// endianness
|
// endianness
|
||||||
if (!raw.byte_order)
|
if (!raw.byte_order)
|
||||||
raw.byte_order = OpenSoundDevice::convert_oss_format_to_endian(afmt);
|
raw.byte_order = OpenSoundDevice::convert_oss_format_to_endian(afmt);
|
||||||
if (raw.byte_order != OpenSoundDevice::convert_oss_format_to_endian(afmt)) {
|
if ((int)raw.byte_order != OpenSoundDevice::convert_oss_format_to_endian(afmt)) {
|
||||||
Close();
|
Close();
|
||||||
return B_MEDIA_BAD_FORMAT;
|
return B_MEDIA_BAD_FORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// channel count
|
// channel count
|
||||||
if (!raw.channel_count)
|
if (raw.channel_count == 0)
|
||||||
raw.channel_count = (unsigned)Info()->min_channels;
|
raw.channel_count = (unsigned)Info()->min_channels;
|
||||||
if (raw.channel_count < Info()->min_channels || raw.channel_count > Info()->max_channels)
|
if ((int)raw.channel_count < Info()->min_channels
|
||||||
|
|| (int)raw.channel_count > Info()->max_channels)
|
||||||
return B_MEDIA_BAD_FORMAT;
|
return B_MEDIA_BAD_FORMAT;
|
||||||
err = SetChannels(raw.channel_count);
|
err = SetChannels(raw.channel_count);
|
||||||
if (err < B_OK) {
|
if (err < B_OK) {
|
||||||
@@ -784,7 +724,7 @@ status_t OpenSoundDeviceEngine::SpecializeFormatFor(int fmt, media_format &forma
|
|||||||
// memcpy(&fFragments, &abinfo, sizeof(abinfo));
|
// memcpy(&fFragments, &abinfo, sizeof(abinfo));
|
||||||
|
|
||||||
// make sure buffer size is less than the driver's own buffer ( /2 to keep some margin )
|
// make sure buffer size is less than the driver's own buffer ( /2 to keep some margin )
|
||||||
if (/*rec && raw.buffer_size &&*/ raw.buffer_size > abinfo.fragsize * abinfo.fragstotal / 4)
|
if (/*rec && raw.buffer_size &&*/ (int)raw.buffer_size > abinfo.fragsize * abinfo.fragstotal / 4)
|
||||||
return B_MEDIA_BAD_FORMAT;
|
return B_MEDIA_BAD_FORMAT;
|
||||||
if (!raw.buffer_size)
|
if (!raw.buffer_size)
|
||||||
raw.buffer_size = abinfo.fragsize;//XXX
|
raw.buffer_size = abinfo.fragsize;//XXX
|
||||||
|
|||||||
@@ -57,19 +57,18 @@ virtual ssize_t Write(const void *buffer, size_t size);
|
|||||||
size_t GetISpace(audio_buf_info *info=NULL);
|
size_t GetISpace(audio_buf_info *info=NULL);
|
||||||
size_t GetOSpace(audio_buf_info *info=NULL);
|
size_t GetOSpace(audio_buf_info *info=NULL);
|
||||||
|
|
||||||
int64 GetCurrentIPtr(int32 *fifoed=NULL, oss_count_t *info=NULL);
|
int64 GetCurrentIPtr(int32* fifoed = NULL,
|
||||||
int64 GetCurrentOPtr(int32 *fifoed=NULL, oss_count_t *info=NULL);
|
oss_count_t* info = NULL);
|
||||||
|
int64 GetCurrentOPtr(int32* fifoed = NULL,
|
||||||
|
size_t* fragmentPos = NULL);
|
||||||
|
|
||||||
int32 GetIOverruns();
|
int32 GetIOverruns();
|
||||||
int32 GetOUnderruns();
|
int32 GetOUnderruns();
|
||||||
|
|
||||||
int GetODelay(void);
|
size_t DriverBufferSize() const;
|
||||||
|
|
||||||
status_t StartRecording(void);
|
status_t StartRecording(void);
|
||||||
|
|
||||||
int64 PlayedFramesCount(void);
|
|
||||||
bigtime_t PlayedRealTime(void);
|
|
||||||
|
|
||||||
// suggest possibles
|
// suggest possibles
|
||||||
status_t WildcardFormatFor(int fmt, media_format &format, bool rec=false);
|
status_t WildcardFormatFor(int fmt, media_format &format, bool rec=false);
|
||||||
// suggest best
|
// suggest best
|
||||||
@@ -90,6 +89,7 @@ friend class OpenSoundAddOn;
|
|||||||
media_format fMediaFormat;
|
media_format fMediaFormat;
|
||||||
int64 fPlayedFramesCount;
|
int64 fPlayedFramesCount;
|
||||||
bigtime_t fPlayedRealTime;
|
bigtime_t fPlayedRealTime;
|
||||||
|
size_t fDriverBufferSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -238,11 +238,10 @@ private:
|
|||||||
status_t _StartRecThread(NodeOutput* output);
|
status_t _StartRecThread(NodeOutput* output);
|
||||||
status_t _StopRecThread(NodeOutput* output);
|
status_t _StopRecThread(NodeOutput* output);
|
||||||
|
|
||||||
void _AllocateBuffers(NodeOutput& channel);
|
|
||||||
BBuffer* _FillNextBuffer(audio_buf_info* abinfo,
|
BBuffer* _FillNextBuffer(audio_buf_info* abinfo,
|
||||||
NodeOutput& channel);
|
NodeOutput& channel);
|
||||||
void _UpdateTimeSource(audio_buf_info* abinfo,
|
void _UpdateTimeSource(bigtime_t performanceTime,
|
||||||
NodeInput& input);
|
bigtime_t realTime, float drift);
|
||||||
|
|
||||||
|
|
||||||
NodeOutput* _FindOutput(
|
NodeOutput* _FindOutput(
|
||||||
@@ -271,9 +270,10 @@ private:
|
|||||||
// and bit rate, not the defaults that are in the
|
// and bit rate, not the defaults that are in the
|
||||||
// parameters
|
// parameters
|
||||||
OpenSoundDevice* fDevice;
|
OpenSoundDevice* fDevice;
|
||||||
|
|
||||||
bool fTimeSourceStarted;
|
bool fTimeSourceStarted;
|
||||||
int64 fOldPlayedFramesCount;
|
bigtime_t fTimeSourceStartTime;
|
||||||
bigtime_t fOldPlayedRealTime;
|
|
||||||
BParameterWeb* fWeb;
|
BParameterWeb* fWeb;
|
||||||
BMessage fConfig;
|
BMessage fConfig;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008 Stephan Aßmus, <superstippi@gmx.de>
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT license.
|
||||||
|
*/
|
||||||
|
#ifndef SUPPORT_FUNCTIONS_H
|
||||||
|
#define SUPPORT_FUNCTIONS_H
|
||||||
|
|
||||||
|
#include <MediaDefs.h>
|
||||||
|
|
||||||
|
static inline int32
|
||||||
|
bytes_per_frame(const media_format& format)
|
||||||
|
{
|
||||||
|
int32 channelCount = format.u.raw_audio.channel_count;
|
||||||
|
size_t sampleSize = format.u.raw_audio.format
|
||||||
|
& media_raw_audio_format::B_AUDIO_SIZE_MASK;
|
||||||
|
return sampleSize * channelCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline bigtime_t
|
||||||
|
time_for_buffer(size_t size, const media_format& format)
|
||||||
|
{
|
||||||
|
int32 frameSize = bytes_per_frame(format);
|
||||||
|
float frameRate = format.u.raw_audio.frame_rate;
|
||||||
|
|
||||||
|
return (bigtime_t)((double)size * 1000000 / frameSize / frameRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // SUPPORT_FUNCTIONS_H
|
||||||
Reference in New Issue
Block a user