2005-03-02 23:49:38 +00:00
# include "rockmacros.h"
# include "defs.h"
# include "pcm.h"
# include "rc.h"
2005-03-28 00:00:24 +00:00
# define RBSOUND
2005-03-02 23:49:38 +00:00
struct pcm pcm ;
2005-03-28 00:00:24 +00:00
# define BUF_SIZE (8192)
# define DMA_PORTION (1024)
static short buf1_unal [ ( BUF_SIZE / sizeof ( short ) ) + 2 ] ; // to make sure 4 byte aligned
2005-03-28 00:27:49 +00:00
rcvar_t pcm_exports [ ] =
{
RCV_END
} ;
# if CONFIG_HWCODEC == MASNONE
2005-03-28 00:00:24 +00:00
static short * buf1 ;
2005-03-02 23:49:38 +00:00
2005-03-28 00:00:24 +00:00
static short front_buf [ 512 ] ;
static short * last_back_pos ;
static bool newly_started ;
static int turns ;
2005-03-02 23:49:38 +00:00
void pcm_init ( void )
{
2005-03-28 00:00:24 +00:00
buf1 = ( signed short * ) ( ( ( ( unsigned int ) buf1_unal ) > > 2 ) < < 2 ) ; /* here i just make sure that buffer is aligned to 4 bytes*/
newly_started = true ;
last_back_pos = buf1 ;
turns = 0 ;
pcm . hz = 11025 ;
pcm . stereo = 1 ;
pcm . buf = front_buf ;
pcm . len = ( sizeof ( front_buf ) ) / sizeof ( short ) ; /* length in shorts, not bytes */
pcm . pos = 0 ;
rb - > pcm_play_stop ( ) ;
rb - > pcm_set_frequency ( 11025 ) ;
rb - > pcm_set_volume ( 200 ) ;
2005-03-02 23:49:38 +00:00
}
void pcm_close ( void )
{
2005-03-28 00:00:24 +00:00
memset ( & pcm , 0 , sizeof pcm ) ;
newly_started = true ;
last_back_pos = buf1 ;
rb - > pcm_play_stop ( ) ;
2005-03-02 23:49:38 +00:00
}
2005-03-28 00:00:24 +00:00
void get_more ( unsigned char * * start , long * size )
{
int length ;
unsigned int sar = ( unsigned int ) SAR0 ;
length = ( ( unsigned int ) buf1 ) + BUF_SIZE - sar ;
if ( turns > 0 )
{
newly_started = true ;
last_back_pos = buf1 ;
turns = 0 ;
return ;
} /* sound will stop if no one feeds data*/
if ( length < = 0 )
{
* start = ( unsigned char * ) buf1 ;
* size = DMA_PORTION ;
turns + + ;
}
else
{
* start = ( unsigned char * ) sar ;
if ( length > DMA_PORTION )
* size = DMA_PORTION ;
else
* size = length ;
}
}
2005-03-02 23:49:38 +00:00
int pcm_submit ( void )
{
2005-03-28 00:00:24 +00:00
while ( ( turns < 0 ) & & ( ( ( ( unsigned int ) last_back_pos ) + pcm . pos * sizeof ( short ) ) > ( ( unsigned int ) SAR0 ) ) & & ! newly_started ) rb - > yield ( ) ; /* wait until data is passed through DAC or until exit*/
int shorts_left = ( ( ( ( unsigned int ) buf1 ) + BUF_SIZE ) - ( ( unsigned int ) last_back_pos ) ) / sizeof ( short ) ;
if ( shorts_left > = pcm . pos )
{
memcpy ( last_back_pos , pcm . buf , pcm . pos * sizeof ( short ) ) ;
last_back_pos = & last_back_pos [ pcm . pos ] ;
}
else
{
int last_pos = shorts_left ;
memcpy ( last_back_pos , pcm . buf , shorts_left * sizeof ( short ) ) ;
last_back_pos = buf1 ;
shorts_left = pcm . pos - shorts_left ;
memcpy ( last_back_pos , & pcm . buf [ last_pos ] , shorts_left * sizeof ( short ) ) ;
last_back_pos = & buf1 [ shorts_left ] ;
turns - - ;
}
if ( newly_started )
{
rb - > pcm_play_data ( ( unsigned char * ) buf1 , pcm . pos * sizeof ( short ) , & get_more ) ;
newly_started = false ;
}
pcm . pos = 0 ;
return 1 ;
2005-03-28 00:27:49 +00:00
}
2005-03-20 23:06:47 +00:00
# else
2005-03-28 00:27:49 +00:00
void pcm_init ( void )
{
pcm . hz = 11025 ;
pcm . stereo = 1 ;
pcm . buf = buf1_unal ;
pcm . len = ( BUF_SIZE / sizeof ( short ) ) ;
2005-03-28 00:00:24 +00:00
pcm . pos = 0 ;
2005-03-02 23:49:38 +00:00
}
2005-03-28 00:27:49 +00:00
void pcm_close ( void )
{
memset ( & pcm , 0 , sizeof pcm ) ;
}
int pcm_submit ( void )
{
pcm . pos = 0 ;
return 0 ;
}
# endif
2005-03-02 23:49:38 +00:00