@ -42,6 +42,7 @@ typedef struct {
int wave_nb_samples ;
int list_voices ;
cst_voice * voice ;
struct voice_entry * voice_entry ;
int64_t pts ;
int frame_nb_samples ; ///< number of samples per frame
} FliteContext ;
@ -64,7 +65,9 @@ AVFILTER_DEFINE_CLASS(flite);
static volatile int flite_inited = 0 ;
/* declare functions for all the supported voices */
# define DECLARE_REGISTER_VOICE_FN(name) cst_voice *register_cmu_us_## name(const char *)
# define DECLARE_REGISTER_VOICE_FN(name) \
cst_voice * register_cmu_us_ # # name ( const char * ) ; \
void unregister_cmu_us_ # # name ( cst_voice * ) ;
DECLARE_REGISTER_VOICE_FN ( awb ) ;
DECLARE_REGISTER_VOICE_FN ( kal ) ;
DECLARE_REGISTER_VOICE_FN ( kal16 ) ;
@ -74,14 +77,22 @@ DECLARE_REGISTER_VOICE_FN(slt);
struct voice_entry {
const char * name ;
cst_voice * ( * register_fn ) ( const char * ) ;
void ( * unregister_fn ) ( cst_voice * ) ;
cst_voice * voice ;
unsigned usage_count ;
} voice_entry ;
# define MAKE_VOICE_STRUCTURE(voice_name) { \
. name = # voice_name , \
. register_fn = register_cmu_us_ # # voice_name , \
. unregister_fn = unregister_cmu_us_ # # voice_name , \
}
static struct voice_entry voice_entries [ ] = {
{ " awb " , register_cmu_us_awb } ,
{ " kal " , register_cmu_us_kal } ,
{ " kal16 " , register_cmu_us_kal16 } ,
{ " rms " , register_cmu_us_rms } ,
{ " slt " , register_cmu_us_slt } ,
MAKE_VOICE_STRUCTURE ( awb ) ,
MAKE_VOICE_STRUCTURE ( kal ) ,
MAKE_VOICE_STRUCTURE ( kal16 ) ,
MAKE_VOICE_STRUCTURE ( rms ) ,
MAKE_VOICE_STRUCTURE ( slt ) ,
} ;
static void list_voices ( void * log_ctx , const char * sep )
@ -92,19 +103,22 @@ static void list_voices(void *log_ctx, const char *sep)
voice_entries [ i ] . name , i < ( n - 1 ) ? sep : " \n " ) ;
}
static int select_voice ( cst_voice * * voic e, const char * voice_name , void * log_ctx )
static int select_voice ( struct voice_entry * * entry_ret , const char * voice_name , void * log_ctx )
{
int i ;
for ( i = 0 ; i < FF_ARRAY_ELEMS ( voice_entries ) ; i + + ) {
struct voice_entry * entry = & voice_entries [ i ] ;
if ( ! strcmp ( entry - > name , voice_name ) ) {
* voice = entry - > register_fn ( NULL ) ;
if ( ! * voice ) {
if ( ! entry - > voice )
entry - > voice = entry - > register_fn ( NULL ) ;
if ( ! entry - > voice ) {
av_log ( log_ctx , AV_LOG_ERROR ,
" Could not register voice '%s' \n " , voice_name ) ;
return AVERROR_UNKNOWN ;
}
entry - > usage_count + + ;
* entry_ret = entry ;
return 0 ;
}
}
@ -142,8 +156,9 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
flite_inited + + ;
}
if ( ( ret = select_voice ( & flite - > voice , flite - > voice_str , ctx ) ) < 0 )
if ( ( ret = select_voice ( & flite - > voice_entry , flite - > voice_str , ctx ) ) < 0 )
return ret ;
flite - > voice = flite - > voice_entry - > voice ;
if ( flite - > textfile & & flite - > text ) {
av_log ( ctx , AV_LOG_ERROR ,
@ -188,8 +203,10 @@ static av_cold void uninit(AVFilterContext *ctx)
av_opt_free ( flite ) ;
delete_voice ( flite - > voice ) ;
if ( ! - - flite - > voice_entry - > usage_count )
flite - > voice_entry - > unregister_fn ( flite - > voice ) ;
flite - > voice = NULL ;
flite - > voice_entry = NULL ;
delete_wave ( flite - > wave ) ;
flite - > wave = NULL ;
}