add binfolder path relative filters, fix gbrp color model, vwdw timebar tweaks, title...
[goodguy/history.git] / cinelerra-5.1 / cinelerra / audiooss.C
index 73340ff1bbe0a9fd4f5ffaaaf5de13577070e07e..cb1fc0877dff906ea8413b5140522e0888f1872d 100644 (file)
@@ -25,6 +25,7 @@
 #include "clip.h"
 #include "condition.h"
 #include "errno.h"
+#include "language.h"
 #include "playbackconfig.h"
 #include "preferences.h"
 #include "recordconfig.h"
@@ -79,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;
@@ -87,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;
@@ -101,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();
@@ -197,15 +210,15 @@ int AudioOSS::open_input()
                                buffer_info = 0x7fff000f;
                        int ret = 1;
                        if(ioctl(dsp_in[i], SNDCTL_DSP_SETFRAGMENT, &buffer_info))
-                               fprintf(stderr, "SNDCTL_DSP_SETFRAGMENT failed.\n");
+                               fprintf(stderr, _("%s failed\n"), "SNDCTL_DSP_SETFRAGMENT");
                        else if(ioctl(dsp_in[i], SNDCTL_DSP_SETFMT, &format) < 0)
-                               fprintf(stderr, "SNDCTL_DSP_SETFMT failed\n");
+                               fprintf(stderr, _("%s failed\n"), "SNDCTL_DSP_SETFMT");
                        else {
                                int channels = device->get_ichannels();
                                if(ioctl(dsp_in[i], SNDCTL_DSP_CHANNELS, &channels) < 0)
-                                       fprintf(stderr, "SNDCTL_DSP_CHANNELS failed\n");
+                                       fprintf(stderr, _("%s failed\n"), "SNDCTL_DSP_CHANNELS");
                                else if(ioctl(dsp_in[i], SNDCTL_DSP_SPEED, &device->in_samplerate) < 0)
-                                       fprintf(stderr, "SNDCTL_DSP_SPEED failed\n");
+                                       fprintf(stderr, _("%s failed\n"), "SNDCTL_DSP_SPEED");
                                else
                                        ret = 0;
                        }
@@ -346,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))
        {
@@ -354,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;
 }
@@ -383,6 +396,17 @@ int AudioOSS::interrupt_playback()
        return 0;
 }
 
+int64_t AudioOSS::samples_output()
+{
+       for( int i=0; i<MAXDEVICES; ++i ) {
+               if( thread[i] ) {
+                       int frame_size = device->get_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;