Commit 02e29e1c authored by Eric Petit's avatar Eric Petit

Rewritten BeOS audio output for audio output 3. It now "pulls" the data.

Sound is yet choppy (I don't know why).
parent da283062
...@@ -142,7 +142,7 @@ case "x${target_os}" in ...@@ -142,7 +142,7 @@ case "x${target_os}" in
CXXFLAGS_save="${CXXFLAGS_save} -Wno-multichar -Wno-ctor-dtor-privacy -Woverloaded-virtual"; CXXFLAGS="${CXXFLAGS_save}" CXXFLAGS_save="${CXXFLAGS_save} -Wno-multichar -Wno-ctor-dtor-privacy -Woverloaded-virtual"; CXXFLAGS="${CXXFLAGS_save}"
LDFLAGS_vlc="${LDFLAGS_vlc} -lbe" LDFLAGS_vlc="${LDFLAGS_vlc} -lbe"
LDFLAGS_plugins="${LDFLAGS_plugins} -nostart" 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" LDFLAGS_ipv4="${LDFLAGS_ipv4} -lbind"
;; ;;
x*) x*)
......
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
* aout.cpp: BeOS audio output * aout.cpp: BeOS audio output
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN * 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> * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
* Eric Petit <titer@videolan.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -27,241 +28,128 @@ ...@@ -27,241 +28,128 @@
*****************************************************************************/ *****************************************************************************/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> /* malloc(), free() */ #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 <malloc.h>
#include <string.h> #include <string.h>
#include <SoundPlayer.h>
#include <vlc/vlc.h> #include <vlc/vlc.h>
#include <vlc/aout.h> #include <vlc/aout.h>
#include "aout_internal.h" #include "aout_internal.h"
/***************************************************************************** /*****************************************************************************
* aout_sys_t: BeOS audio output method descriptor * 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; BSoundPlayer *p_player;
gs_audio_format * p_format; float *p_buffer;
void * p_buffer; size_t i_buffer_size;
int i_buffer_size; } aout_sys_t;
uint i_buffer_pos;
mtime_t clock_diff;
};
#define FRAME_SIZE 2048 #define FRAME_SIZE 2048
/***************************************************************************** /*****************************************************************************
* Local prototypes. * Local prototypes.
*****************************************************************************/ *****************************************************************************/
static int SetFormat ( aout_instance_t * ); static void Play ( void *p_aout, void *p_buffer, size_t size,
static void Play ( aout_instance_t * ); const media_raw_audio_format &format );
static int BeOSThread ( aout_instance_t * ); static void DoNothing ( aout_instance_t *p_aout );
/***************************************************************************** /*****************************************************************************
* OpenAudio: opens a BPushGameSound * OpenAudio
*****************************************************************************/ *****************************************************************************/
int E_(OpenAudio) ( vlc_object_t * p_this ) int E_(OpenAudio) ( vlc_object_t * p_this )
{ {
aout_instance_t * p_aout = (aout_instance_t *)p_this; aout_instance_t *p_aout = (aout_instance_t*) p_this;
struct aout_sys_t * p_sys; p_aout->output.p_sys = (aout_sys_t *) malloc( sizeof( aout_sys_t ) );
/* Allocate structure */ aout_sys_t *p_sys = p_aout->output.p_sys;
p_aout->output.p_sys = p_sys = (aout_sys_t *)malloc( sizeof( struct aout_sys_t ) ); p_sys->i_buffer_size = 0;
memset( p_sys, 0, sizeof( struct aout_sys_t ) ); p_sys->p_buffer = NULL;
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;
}
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 ); 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) p_aout->output.output.i_format = VLC_FOURCC('f','l','3','2');
{ p_aout->output.i_nb_samples = FRAME_SIZE;
case VLC_FOURCC('s','1','6','l'): p_aout->output.pf_play = DoNothing;
p_aout->output.p_sys->p_format->format = gs_audio_format::B_GS_S16; p_aout->output.output.i_rate = 44100;
p_aout->output.p_sys->p_format->byte_order = B_MEDIA_LITTLE_ENDIAN; p_aout->output.output.i_channels = 2;
break;
case VLC_FOURCC('s','1','6','b'): p_sys->p_player = new BSoundPlayer( "player", Play, NULL, p_this );
p_aout->output.p_sys->p_format->format = gs_audio_format::B_GS_S16; p_sys->p_player->Start();
p_aout->output.p_sys->p_format->byte_order = B_MEDIA_BIG_ENDIAN; p_sys->p_player->SetHasData( true );
break;
case VLC_FOURCC('s','8',0,0): return 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 )
{
} }
/***************************************************************************** /*****************************************************************************
* CloseAudio: closes the dsp audio device * CloseAudio
*****************************************************************************/ *****************************************************************************/
void E_(CloseAudio) ( vlc_object_t *p_this ) void E_(CloseAudio) ( vlc_object_t *p_this )
{ {
aout_instance_t * p_aout = (aout_instance_t *)p_this; aout_instance_t * p_aout = (aout_instance_t *) p_this;
aout_sys_t * p_sys = (aout_sys_t *) p_aout->output.p_sys;
p_aout->output.p_sys->p_sound->UnlockCyclic();
p_aout->output.p_sys->p_sound->StopPlaying( );
delete p_aout->output.p_sys->p_sound;
p_sys->p_player->Stop();
p_aout->b_die = 1; p_aout->b_die = 1;
free( p_aout->output.p_sys->p_format ); delete p_sys->p_player;
free( p_aout->output.p_sys ); free( 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 );
} }
/***************************************************************************** /*****************************************************************************
* 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; float *p_buffer = (float*) buffer;
p_sys->p_sound->StartPlaying( ); if( format.format != media_raw_audio_format::B_AUDIO_FLOAT )
p_sys->p_sound->LockForCyclic( &p_sys->p_buffer,
(size_t *)&p_sys->i_buffer_size );
while ( !p_aout->b_die )
{ {
aout_buffer_t * p_buffer; msg_Err( p_aout, "Bad audio format" );
int i_tmp, i_size; return;
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 );
p_aout->p_vlc->pf_memcpy( (void *)((int)p_aout->output.p_sys->p_buffer), if( p_sys->i_buffer_size < size )
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 ) ); p_aout_buffer = aout_FifoPop( p_aout, &p_aout->output.fifo );
if( p_aout_buffer != NULL )
i_buffer_pos = i_newbuf_pos - i_buffer_pos;
}
else
{ {
p_aout->p_vlc->pf_memcpy( (void *)((int)p_aout->output.p_sys->p_buffer + i_buffer_pos), if( p_sys->p_buffer == NULL )
p_buffer->p_buffer, p_buffer->i_size ); {
p_sys->p_buffer = (float*)malloc( p_aout_buffer->i_nb_bytes );
i_buffer_pos = i_newbuf_pos; 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;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment