Rewritten BeOS audio output for audio output 3. It now "pulls" the data.
authorEric Petit <titer@videolan.org>
Sat, 12 Oct 2002 12:24:52 +0000 (12:24 +0000)
committerEric Petit <titer@videolan.org>
Sat, 12 Oct 2002 12:24:52 +0000 (12:24 +0000)
Sound is yet choppy (I don't know why).

configure.ac.in
modules/gui/beos/AudioOutput.cpp

index 8dbded7..595b8e9 100644 (file)
@@ -142,7 +142,7 @@ case "x${target_os}" in
     CXXFLAGS_save="${CXXFLAGS_save} -Wno-multichar -Wno-ctor-dtor-privacy -Woverloaded-virtual"; CXXFLAGS="${CXXFLAGS_save}"
     LDFLAGS_vlc="${LDFLAGS_vlc} -lbe"
     LDFLAGS_plugins="${LDFLAGS_plugins} -nostart"
-    LDFLAGS_beos="${LDFLAGS_beos} -lbe -lgame -lroot -ltracker -lstdc++.r4 -ltranslation"
+    LDFLAGS_beos="${LDFLAGS_beos} -lbe -lmedia -lroot -ltracker -lstdc++.r4 -ltranslation"
     LDFLAGS_ipv4="${LDFLAGS_ipv4} -lbind"
     ;;
   x*)
index e61e26f..b9e04c0 100644 (file)
@@ -2,10 +2,11 @@
  * aout.cpp: BeOS audio output
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: AudioOutput.cpp,v 1.9 2002/10/09 01:14:18 titer Exp $
+ * $Id: AudioOutput.cpp,v 1.10 2002/10/12 12:24:52 titer Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
+ *          Eric Petit <titer@videolan.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  *****************************************************************************/
 #include <stdio.h>
 #include <stdlib.h>                                      /* malloc(), free() */
-#include <kernel/OS.h>
-#include <View.h>
-#include <Application.h>
-#include <Message.h>
-#include <Locker.h>
-#include <media/MediaDefs.h>
-#include <game/PushGameSound.h>
 #include <malloc.h>
 #include <string.h>
 
+#include <SoundPlayer.h>
+
 #include <vlc/vlc.h>
 #include <vlc/aout.h>
 #include "aout_internal.h"
 
 /*****************************************************************************
  * aout_sys_t: BeOS audio output method descriptor
- *****************************************************************************
- * This structure is part of the audio output thread descriptor.
- * It describes some BeOS specific variables.
  *****************************************************************************/
-struct aout_sys_t
+
+typedef struct aout_sys_t
 {
-    BPushGameSound   * p_sound;
-    gs_audio_format  * p_format;
-    void             * p_buffer;
-    int                 i_buffer_size;
-    uint             i_buffer_pos;
-    mtime_t          clock_diff;
-};
+    BSoundPlayer *p_player;
+    float *p_buffer;
+    size_t i_buffer_size;
+} aout_sys_t;
 
 #define FRAME_SIZE 2048
 
 /*****************************************************************************
  * Local prototypes.
  *****************************************************************************/
-static int  SetFormat    ( aout_instance_t * );
-static void Play         ( aout_instance_t * );
-static int  BeOSThread   ( aout_instance_t * );
+static void Play         ( void *p_aout, void *p_buffer, size_t size,
+                           const media_raw_audio_format &format );
+static void DoNothing    ( aout_instance_t *p_aout );
 
 /*****************************************************************************
- * OpenAudio: opens a BPushGameSound
+ * OpenAudio
  *****************************************************************************/
 int E_(OpenAudio) ( vlc_object_t * p_this )
-{       
-    aout_instance_t * p_aout = (aout_instance_t *)p_this;
-    struct aout_sys_t * p_sys;
-
-    /* Allocate structure */
-    p_aout->output.p_sys = p_sys = (aout_sys_t *)malloc( sizeof( struct aout_sys_t ) );
-    memset( p_sys, 0, sizeof( struct aout_sys_t ) );
-    if( p_sys == NULL )
-    {
-        msg_Err( p_aout, "out of memory" );
-        return -1;
-    }
-    
-    /* Initialize format */
-    p_sys->p_format = (gs_audio_format *)malloc( sizeof( struct gs_audio_format));
-    SetFormat(p_aout);
-
-    /* Allocate BPushGameSound */
-    p_sys->p_sound = new BPushGameSound( 8192,
-                                         p_sys->p_format,
-                                         2, NULL );
-    if( p_sys->p_sound->InitCheck() != B_OK )
-    {
-        free( p_sys->p_format );
-        free( p_sys );
-        msg_Err( p_aout, "cannot initialize BPushGameSound" );
-        return -1;
-    }
+{
+       aout_instance_t *p_aout = (aout_instance_t*) p_this;
+       p_aout->output.p_sys = (aout_sys_t *) malloc( sizeof( aout_sys_t ) );
+       
+       aout_sys_t *p_sys = p_aout->output.p_sys;
+    p_sys->i_buffer_size = 0;
+    p_sys->p_buffer = NULL;
 
-    if( vlc_thread_create( p_aout, "aout", BeOSThread,
-                           VLC_THREAD_PRIORITY_OUTPUT, VLC_FALSE ) )
-    {
-        msg_Err( p_aout, "cannot create aout thread" );
-        delete p_sys->p_sound;
-        free( p_sys->p_format );
-        free( p_sys );
-        return -1;
-    }
-    
-    p_aout->output.pf_play = Play;
     aout_VolumeSoftInit( p_aout );
-
-    return 0;
-}
-
-/*****************************************************************************
- * SetFormat: sets the dsp output format
- *****************************************************************************/
-static int SetFormat( aout_instance_t *p_aout )
-{
-    /* Initialize some variables */
-    p_aout->output.p_sys->p_format->frame_rate = p_aout->output.output.i_rate;
-    p_aout->output.p_sys->p_format->channel_count = p_aout->output.output.i_channels;
     
-    switch (p_aout->output.output.i_format)
-    {
-    case VLC_FOURCC('s','1','6','l'):
-        p_aout->output.p_sys->p_format->format = gs_audio_format::B_GS_S16;
-        p_aout->output.p_sys->p_format->byte_order = B_MEDIA_LITTLE_ENDIAN;
-        break;
-    case VLC_FOURCC('s','1','6','b'):
-        p_aout->output.p_sys->p_format->format = gs_audio_format::B_GS_S16;
-        p_aout->output.p_sys->p_format->byte_order = B_MEDIA_BIG_ENDIAN;
-        break;
-    case VLC_FOURCC('s','8',0,0):
-        p_aout->output.p_sys->p_format->format = gs_audio_format::B_GS_U8;
-        p_aout->output.p_sys->p_format->byte_order = B_MEDIA_LITTLE_ENDIAN;
-        break;
-    case VLC_FOURCC('f','1','3','2'):
-        p_aout->output.p_sys->p_format->format = gs_audio_format::B_GS_F;
-        p_aout->output.p_sys->p_format->byte_order = B_MEDIA_LITTLE_ENDIAN;
-        break;
-    default:
-        msg_Err( p_aout, "cannot set audio format (%i)",
-                          p_aout->output.output.i_format );
-        return -1;
-    }
-
-    p_aout->output.p_sys->p_format->buffer_size = 4*8192;
-
-    return( 0 );
-}
-
-/*****************************************************************************
- * Play: nothing to do
- *****************************************************************************/
-static void Play( aout_instance_t *p_aout )
-{
+    p_aout->output.output.i_format = VLC_FOURCC('f','l','3','2');
+    p_aout->output.i_nb_samples = FRAME_SIZE;
+    p_aout->output.pf_play = DoNothing;
+    p_aout->output.output.i_rate = 44100;
+    p_aout->output.output.i_channels = 2;
+
+    p_sys->p_player = new BSoundPlayer( "player", Play, NULL, p_this );
+    p_sys->p_player->Start();
+    p_sys->p_player->SetHasData( true );
+        
+    return 0;
 }
 
 /*****************************************************************************
- * CloseAudio: closes the dsp audio device
+ * CloseAudio
  *****************************************************************************/
 void E_(CloseAudio) ( vlc_object_t *p_this )
-{       
-    aout_instance_t * p_aout = (aout_instance_t *)p_this;
-
-    p_aout->output.p_sys->p_sound->UnlockCyclic();
-    p_aout->output.p_sys->p_sound->StopPlaying( );
-    delete p_aout->output.p_sys->p_sound;
+{
+    aout_instance_t * p_aout = (aout_instance_t *) p_this;
+    aout_sys_t * p_sys = (aout_sys_t *) p_aout->output.p_sys;
     
+    p_sys->p_player->Stop();
     p_aout->b_die = 1;
-    free( p_aout->output.p_sys->p_format );
-    free( p_aout->output.p_sys );
-}
-
-/*****************************************************************************
- * GetBufInfo: buffer status query
- *****************************************************************************
- * This function fills in the audio_buf_info structure :
- * - returns : number of available fragments (not partially used ones)
- * - int fragstotal : total number of fragments allocated
- * - int fragsize : size of a fragment in bytes
- * - int bytes : available space in bytes (includes partially used fragments)
- * Note! 'bytes' could be more than fragments*fragsize
- *****************************************************************************/
-static int GetBufInfo( aout_instance_t * p_aout )
-{
-    /* returns the allocated space in bytes */
-    return ( p_aout->output.p_sys->p_format->buffer_size );
+    delete p_sys->p_player;
+    free( p_sys );
 }
 
 /*****************************************************************************
- * BeOSThread: asynchronous thread used to DMA the data to the device
+ * Play
  *****************************************************************************/
-static int BeOSThread( aout_instance_t * p_aout )
+static void Play( void *aout, void *buffer, size_t size,
+                  const media_raw_audio_format &format )
 {
-    struct aout_sys_t * p_sys = p_aout->output.p_sys;
+    aout_buffer_t * p_aout_buffer;
+    aout_instance_t *p_aout = (aout_instance_t*) aout;
+    aout_sys_t *p_sys = p_aout->output.p_sys;
 
-    static uint i_buffer_pos;
-
-    p_sys->p_sound->StartPlaying( );
-    p_sys->p_sound->LockForCyclic( &p_sys->p_buffer,
-                                   (size_t *)&p_sys->i_buffer_size );
-
-    while ( !p_aout->b_die )
+    float *p_buffer = (float*) buffer;
+    
+    if( format.format != media_raw_audio_format::B_AUDIO_FLOAT )
     {
-        aout_buffer_t * p_buffer;
-        int i_tmp, i_size;
-        byte_t * p_bytes;
-
-        mtime_t next_date = 0;
-        /* Get the presentation date of the next write() operation. It
-         * is equal to the current date + duration of buffered samples.
-         * Order is important here, since GetBufInfo is believed to take
-         * more time than mdate(). */
-        next_date = (mtime_t)GetBufInfo( p_aout ) * 1000000
-                  / p_aout->output.output.i_bytes_per_frame
-                  / p_aout->output.output.i_rate
-                  * p_aout->output.output.i_frame_length;
-        next_date += mdate();
-
-        p_buffer = aout_OutputNextBuffer( p_aout, next_date, VLC_FALSE );
-        int i_newbuf_pos;
-        if ( p_buffer != NULL )
-        {
-            p_bytes = p_buffer->p_buffer;
-            i_size = p_buffer->i_nb_bytes;
-        }
-        else
-        {
-            i_size = FRAME_SIZE / p_aout->output.output.i_frame_length
-                      * p_aout->output.output.i_bytes_per_frame;
-            p_bytes = (byte_t *)malloc( i_size );
-            memset( p_bytes, 0, i_size );
-        }
-   
-        if( (i_newbuf_pos = i_buffer_pos + p_buffer->i_size)
-                            > p_aout->output.p_sys->i_buffer_size )
-        {
-            p_aout->p_vlc->pf_memcpy( (void *)((int)p_aout->output.p_sys->p_buffer
-                            + i_buffer_pos),
-                              p_buffer->p_buffer,
-                              p_aout->output.p_sys->i_buffer_size - i_buffer_pos );
+        msg_Err( p_aout, "Bad audio format" );
+        return;
+    }
 
-            p_aout->p_vlc->pf_memcpy( (void *)((int)p_aout->output.p_sys->p_buffer),
-                            p_buffer->p_buffer + p_aout->output.p_sys->i_buffer_size - i_buffer_pos,
-                            p_buffer->i_size - ( p_aout->output.p_sys->i_buffer_size - i_buffer_pos ) );
-        
-            i_buffer_pos = i_newbuf_pos - i_buffer_pos;
-        }
-        else
+    if( p_sys->i_buffer_size < size )
+    {
+        p_aout_buffer = aout_FifoPop( p_aout, &p_aout->output.fifo );
+        if( p_aout_buffer != NULL )
         {
-           p_aout->p_vlc->pf_memcpy( (void *)((int)p_aout->output.p_sys->p_buffer + i_buffer_pos),
-                    p_buffer->p_buffer, p_buffer->i_size );
-
-           i_buffer_pos = i_newbuf_pos;
+            if( p_sys->p_buffer == NULL )
+            {
+                p_sys->p_buffer = (float*)malloc( p_aout_buffer->i_nb_bytes );
+                p_sys->i_buffer_size = p_aout_buffer->i_nb_bytes;
+            }
+            else
+            {
+                realloc( p_sys->p_buffer,
+                         p_sys->i_buffer_size + p_aout_buffer->i_nb_bytes );
+                memcpy( p_sys->p_buffer + p_sys->i_buffer_size,
+                        p_aout_buffer->p_buffer,
+                        p_aout_buffer->i_nb_bytes );
+                p_sys->i_buffer_size += p_aout_buffer->i_nb_bytes;
+            }
         }
     }
-    
-    return 0;
 
+    if( p_sys->i_buffer_size >= size )
+    {
+        memcpy( p_buffer, p_sys->p_buffer,
+                MIN( size, p_sys->i_buffer_size ) );
+        p_sys->i_buffer_size -=  MIN( size, p_sys->i_buffer_size );
+    }
 }
 
+/*****************************************************************************
+ * DoNothing 
+ *****************************************************************************/
+static void DoNothing( aout_instance_t *p_aout)
+{
+    return;
+}