X-Git-Url: http://git.cinelerra-gg.org/git/?p=goodguy%2Fhistory.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Faudiooss.C;h=cb1fc0877dff906ea8413b5140522e0888f1872d;hp=f75ff0fbd7248f2eb7a95b020d9dfe710019bcf3;hb=a19a685a46ddc630010788707d9e5b9d2342af46;hpb=0b78779e9e75131eee81d2e4689b98df0e91c092 diff --git a/cinelerra-5.1/cinelerra/audiooss.C b/cinelerra-5.1/cinelerra/audiooss.C index f75ff0fb..cb1fc087 100644 --- a/cinelerra-5.1/cinelerra/audiooss.C +++ b/cinelerra-5.1/cinelerra/audiooss.C @@ -80,6 +80,14 @@ OSSThread::~OSSThread() void OSSThread::run() { +// this makes the longest (blocking) write 1024 samples +// if this is not done, the video can be jerky + AudioDevice *audio_device = device->device; + int frame_size = audio_device->get_ochannels() * audio_device->get_obits()/8; + int maxsz = 1024*frame_size, blksz = maxsz; + ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &blksz); + if( blksz > maxsz ) blksz = maxsz; + while(!done) { input_lock->lock("OSSThread::run 1"); if(done) return; @@ -88,11 +96,14 @@ void OSSThread::run() read_lock->unlock(); } else if(wr) { + if( !bytes_written ) + timer->update(); int count = bytes; unsigned char *bp = data; - while( count > 0 ) { + while( count > 0 && !done ) { Thread::enable_cancel(); - int ret = write(fd, bp, bytes); + int len = count>blksz ? blksz : count; + int ret = write(fd, bp, len); Thread::disable_cancel(); if( ret < 0 ) break; bp += ret; @@ -102,6 +113,7 @@ void OSSThread::run() if( !ioctl(fd, SNDCTL_DSP_GETODELAY, &delay) ) this->delay = delay; bytes_written += ret; + timer->update(); timer_lock->unlock(); } write_lock->unlock(); @@ -347,6 +359,14 @@ int AudioOSS::set_cloexec_flag(int desc, int value) int64_t AudioOSS::device_position() { + for (int i = 0; i < MAXDEVICES; i++) { + if( thread[i] ) { + int frame_size = device->get_ochannels() * device->get_obits()/8; + int64_t pos = thread[i]->device_position() / frame_size; + int64_t tmr = thread[i]->timer->get_scaled_difference(device->out_samplerate); + return pos + tmr; + } + } count_info info; if(!ioctl(get_output(0), SNDCTL_DSP_GETOPTR, &info)) { @@ -355,16 +375,8 @@ int64_t AudioOSS::device_position() // the problem is that if the first write to sound device was not full lenght fragment then // _GETOPTR returns insanely large numbers at first moments of play if (info.bytes > 2100000000) return 0; - int frame = device->get_ochannels() * device->get_obits()/8; - return info.bytes / frame; - } - for (int i = 0; i < MAXDEVICES; i++) - { - if (thread[i]) - return thread[i]->device_position() / - device->get_ochannels() / - (device->get_obits()/8) + - thread[i]->timer->get_scaled_difference(device->out_samplerate); + int frame_size = device->get_ochannels() * device->get_obits()/8; + return info.bytes / frame_size; } return 0; } @@ -384,6 +396,17 @@ int AudioOSS::interrupt_playback() return 0; } +int64_t AudioOSS::samples_output() +{ + for( int i=0; iget_ochannels() * device->get_obits()/8; + return thread[i]->bytes_written / frame_size; + } + } + return 0; +} + int AudioOSS::read_buffer(char *buffer, int bytes) { int sample_size = device->get_ibits() / 8;