コード例 #1
0
static void _on_response( void* context, int res_status, TtsSynthResponseData* response_data )
{
   TtsProviderRequest *provider_request = (TtsProviderRequest*) context;
   unsigned int delta = roadmap_time_get_millis() - provider_request->start_time;
   int matched_count;

   roadmap_log( ROADMAP_DEBUG, TTS_LOG_STR( "Request was completed in %d ms. Status: %d" ), delta, res_status );

   if ( res_status == TTS_RES_STATUS_SUCCESS )
   {
      // Call the process received one more time - for sure ( if progress was not called for the last chunk )
      matched_count = _process_received( provider_request, response_data );

      roadmap_log( ROADMAP_DEBUG, TTS_LOG_STR( "Received %d elements in tts response. Matched: %d. Requested: %d" ),
            response_data->count, matched_count, provider_request->idx_list_count );

   }
   else
   {
      roadmap_log( ROADMAP_ERROR, TTS_LOG_STR( "Error in response" ) );
      _process_error( provider_request );
   }

   // Deallocate the context
   _provider_ctx_free( provider_request );

   sgActiveRequestsCount--;

   // Commit the remaining entries in the queue if existing
   tts_commit();
}
コード例 #2
0
BOOL tts_playlist_add( TtsPlayList list, const char* text )
{
   int result = -1;
   const TtsProvider* provider = NULL;

   if ( !tts_enabled() )
      return FALSE;

   if ( !text )
   {
      roadmap_log( ROADMAP_ERROR, TTS_LOG_STR( "Cannot add NULL texts to the playlist" ) );
      return FALSE;
   }

   provider = _voice_service_provider( list->voice_id );
   switch ( provider->storage_type )
   {
      case __tts_db_data_storage__file:
      {
         TtsPath path;
         const char* parsed_text = _parse_text( text );
         if ( tts_cache_get( parsed_text, list->voice_id, NULL, &path ) )
         {
            result = roadmap_sound_list_add( list->sound_list, path.path );
            roadmap_log( ROADMAP_DEBUG, TTS_LOG_STR( "Adding text %s (Voice: %s). Path: %s to the playlist. Status: %d" ),
                  parsed_text, list->voice_id, path.path, result );

            if ( result == SND_LIST_ERR_NO_FILE )
            {
               const TtsDbEntry* db_entry = tts_db_entry( list->voice_id, parsed_text, NULL );
               TtsTextType text_type = tts_db_text_type( db_entry );

               roadmap_log( ROADMAP_WARNING, TTS_LOG_STR( "File %s doesn't exist!!!. Removing the entry!" ), path.path );
               tts_cache_remove( parsed_text, list->voice_id, __tts_db_data_storage__file );
               // Post new request if matches the current voice
               if ( !list->voice_id || !strcmp( list->voice_id, sgTtsVoiceId ) )
               {
                  tts_request_ex( parsed_text, text_type, NULL, NULL, TTS_FLAG_NONE );
                  tts_commit(); // Commit immediately in this case
               }
            }
         }
         break;
      }
      case __tts_db_data_storage__blob_record:
      {
         TtsData data;
         if ( tts_cache_get( _parse_text( text ), list->voice_id, &data, NULL ) )
            result = roadmap_sound_list_add_buf( list->sound_list, data.data, data.data_size );
         break;
      }
      default:
      {
         roadmap_log( ROADMAP_WARNING, "Data storage type %d is not supported" );
      }
   }

   return ( result >= 0 );
}
コード例 #3
0
BOOL tts_update_provider( const TtsProvider* tts_provider )
{
   int i;
   BOOL result = TRUE;
   for( i = 0; i < TTS_PROVIDERS_MAX_NUM; ++i )
   {
      if ( sgTtsProviders[i].registered &&
            !strcmp( sgTtsProviders[i].provider_name, tts_provider->provider_name ) )
      {
         sgTtsProviders[i] = *tts_provider; // Bit copy.
         sgTtsProviders[i].registered = TRUE;
         tts_voices_update( sgTtsProviders[i].provider_name, sgTtsProviders[i].voices_cfg );

         roadmap_log( ROADMAP_INFO, TTS_LOG_STR( "Provider %s was updated successfully" ), tts_provider->provider_name );
         break;
      }
   }
   if ( i == TTS_PROVIDERS_MAX_NUM )
   {
      roadmap_log( ROADMAP_ERROR, TTS_LOG_STR( "Cannot find registered provider with name %s" ), tts_provider->provider_name );
      result = FALSE;
   }
   else
   {
      const char* voice_id = sgTtsVoiceId;
      if ( sgTtsVoiceId )
      {
         const TtsVoice* voice;
         voice = tts_voices_get( sgTtsVoiceId, NULL );
         // If not valid voice - replace to default
         if ( !TTS_VOICE_VALID( voice ) )
         {
            roadmap_log( ROADMAP_WARNING, TTS_LOG_STR( "Voice %s is invalidated. Trying to set the default one" ), voice->voice_id );
            voice_id = sgTtsDefaultVoiceId;
         }
      }
      else
      {
         roadmap_log( ROADMAP_WARNING, TTS_LOG_STR( "There is no voice defined. Setting the default one" ) );
         voice_id = sgTtsDefaultVoiceId;
      }

      tts_set_voice( voice_id );
      tts_ui_initialize();
   }

   return result;
}
コード例 #4
0
static int _process_error( const TtsProviderRequest* provider_request )
{
   int queue_idx, i, res_status = TTS_RES_STATUS_ERROR;
   int count = 0;
   TtsRequest* tts_request;
   char* text;
   BOOL apply_retry = FALSE;

   for ( i = 0, count = 0; i < provider_request->idx_list_count; ++i )
   {
      queue_idx = provider_request->idx_list[i];
      if ( tts_queue_is_empty( queue_idx ) )
         continue;

      tts_request = tts_queue_get_context( queue_idx );

      apply_retry = _apply_retry( tts_request, queue_idx, &res_status );

      _run_request_callbacks( tts_request, res_status );

      roadmap_log( ROADMAP_WARNING, TTS_LOG_STR( "Error reported for text: %s" ), tts_request->text );

      if ( !apply_retry )
      {
         text = (char*) tts_queue_get_key( queue_idx );
         tts_queue_remove( queue_idx );

         free( text );
      }
      count++;
   }

   return count;
}
コード例 #5
0
void tts_initialize( void )
{
   // Load the configuraiton
   tts_load_config();

   // Set the comfiguration to the Server defined
   if ( !sgTtsVoiceId[0] || !strcmp( sgTtsVoiceId, TTS_CFG_VOICE_ID_NOT_DEFINED ) )
   {
      roadmap_config_set( &RMConfigTTSVoiceId, sgTtsDefaultVoiceId );
      sgTtsVoiceId = sgTtsDefaultVoiceId;
   }

   // Voices initialization
   tts_voices_initialize( _voice_updated );

   // Queue initialization
   tts_queue_init();

   // Cache initialization
   tts_cache_initialize();

   // Provider context pool initialization
   _provider_ctx_init();

   if ( !tts_feature_enabled() )
      return;

   // Find active provider
   if ( !( sgActiveProvider = _voice_service_provider( sgTtsVoiceId ) ) )
   {
      roadmap_log( ROADMAP_WARNING, TTS_LOG_STR( "Provider is not registered for current voice id: %s." ), sgTtsVoiceId );
      sgTtsVoiceId = sgTtsDefaultVoiceId;
      if ( !( sgActiveProvider = _voice_service_provider( sgTtsVoiceId ) ) )
      {
         roadmap_log( ROADMAP_ERROR, TTS_LOG_STR( "Critical TTS Engine error. Provider is not registered for default voice id: %s." ), sgTtsVoiceId );
         return;
      }
   }

   if ( sgActiveProvider->prepare_cb )
      sgActiveProvider->prepare_cb();

   sgActiveRequestsCount = 0;

   // Cache voice
   tts_cache_set_voice( sgTtsVoiceId, sgActiveProvider->storage_type );
}
コード例 #6
0
static BOOL _process_cached( const TtsRequest* request_ctx )
{
   BOOL result = TRUE;

   roadmap_log( ROADMAP_DEBUG, TTS_LOG_STR( "Processing cached element: %s" ), request_ctx->text );

   _run_request_callbacks( request_ctx, TTS_RES_STATUS_SUCCESS );

   return result;
}
コード例 #7
0
void tts_request_ex( const char* text, TtsTextType text_type, TtsRequestCompletedCb completed_cb, void* user_context, int flags )
{
   const char *parsed_text;

   if ( !tts_enabled() )
   {
      roadmap_log(ROADMAP_WARNING, TTS_LOG_STR( "TTS is disabled cannot post synthesize request for %s." ), text );
      return;
   }

   if ( !text || !text[0] )
   {
      if ( completed_cb )
      {
         completed_cb( user_context, TTS_RES_STATUS_NULL_TEXT, "NULL" );
      }
      roadmap_log( ROADMAP_WARNING, TTS_LOG_STR( "NULL or empty text cannot be requested!" ) );
      return;
   }

   parsed_text = _parse_text( text );

   if ( tts_cache_exists( parsed_text, sgTtsVoiceId ) )
   {
      TtsRequest tts_request = TTS_REQUEST_INITIALIZER;
      tts_request.flags = flags;
      tts_request.text = parsed_text;
      _add_request_callback( &tts_request, completed_cb, user_context );

      _process_cached( &tts_request );
   }
   else
   {
      _queue_one( strdup( parsed_text ), text_type, completed_cb, user_context, flags );

      if ( sgActiveProvider->batch_request_limit == 1 )
      {
         // Commit immediately
         tts_commit();
      }
   }
}
コード例 #8
0
ファイル: tts_db.c プロジェクト: Daoudai/waze-qt
BOOL tts_db_get_path( const TtsDbEntry* entry, TtsPath* db_path )
{
   TtsDbDataStorageType storage_type;

   BOOL result = FALSE;

   result = tts_db_sqlite_get_info( entry, NULL, &storage_type, db_path );

   if ( !result )
   {
      roadmap_log( ROADMAP_WARNING, TTS_LOG_STR( "Error retrieving the path!" ) );
   }
   if ( !( storage_type & __tts_db_data_storage__file ) )
   {
      roadmap_log( ROADMAP_WARNING, TTS_LOG_STR( "Request for path for the non fs storage record!" ) );
   }

   result = ( result && db_path->path[0] );

   return result;
}
コード例 #9
0
void tts_set_voice( const char* voice_id )
{
   const TtsProvider* provider;

   if ( !tts_feature_enabled() )
      return;

   if ( !voice_id || ( sgActiveProvider && !strcmp( voice_id, sgTtsVoiceId ) ) )
      return;

   roadmap_log( ROADMAP_INFO, TTS_LOG_STR( "Voice change request: %s => %s" ), SAFE_STR( sgTtsVoiceId ), SAFE_STR( voice_id ) );

   // Find active provider
   if ( !( provider = _voice_service_provider( voice_id ) ) )
   {
      roadmap_log( ROADMAP_ERROR, TTS_LOG_STR( "Critical TTS Engine error. Provider is not registered for voice id: %s." ), sgTtsVoiceId );
      return;
   }

   if ( !TTS_VOICE_VALID( tts_voices_get( voice_id, NULL ) ) )
   {
      roadmap_log( ROADMAP_WARNING, TTS_LOG_STR( "Current voice %s is not valid. Server may not support the requests" ), voice_id );
   }

   sgActiveProvider = provider;
   sgActiveRequestsCount = 0;

   if ( sgActiveProvider->prepare_cb )
      sgActiveProvider->prepare_cb();

   sgTtsVoiceId = voice_id;

   tts_cache_set_voice( sgTtsVoiceId, sgActiveProvider->storage_type );

   roadmap_config_set( &RMConfigTTSVoiceId, sgTtsVoiceId );

   _voice_changed( sgTtsVoiceId, FALSE );

}
コード例 #10
0
static BOOL _apply_retry( TtsRequest* tts_request, int queue_idx, int* status )
{
   BOOL apply_retry = FALSE;

   if ( tts_request->flags & TTS_FLAG_RETRY )
   {
      if ( tts_request->retry_index < TTS_RETRY_COUNT )
      {
         apply_retry = TRUE;
         *status |= TTS_RES_STATUS_RETRY_ON;
         tts_request->retry_index++;
         tts_queue_set_status( queue_idx, TTS_QUEUE_STATUS_IDLE );
         roadmap_log( ROADMAP_WARNING, TTS_LOG_STR( "Applying retry #%d ( %d ) for text: %s" ), tts_request->retry_index, TTS_RETRY_COUNT, tts_request->text );
      }
      else
      {
         *status |= TTS_RES_STATUS_RETRY_EXHAUSTED;
         roadmap_log( ROADMAP_WARNING, TTS_LOG_STR( "Retries number exhausted #%d ( %d ) for text: %s. Giving up ... " ), tts_request->retry_index, TTS_RETRY_COUNT, tts_request->text );
      }
   }

   return apply_retry;
}
コード例 #11
0
/*
 ******************************************************************************
 * Queue one TTS request.
 * Auxiliary
 */
static void _queue_one( const char* text, TtsTextType text_type, TtsRequestCompletedCb completed_cb, void* user_context, int flags )
{
   // Check if already requested in the queue
   int queue_idx;

   roadmap_log( ROADMAP_DEBUG, TTS_LOG_STR( "Adding text %s to the queue!" ), text );

   if ( text == NULL )
   {
      roadmap_log( ROADMAP_ERROR, TTS_LOG_STR( "Cannot prepare NULL text." ) );
      return;
   }

   queue_idx = tts_queue_get_index( text );
   if (queue_idx >= 0) {
      TtsRequest* request = tts_queue_get_context( queue_idx );

      _add_request_callback( request, completed_cb, user_context );

      return;
   }

   // Queue. Text duplicated in parser
   queue_idx = tts_queue_add( NULL, text );

   // Set the context
   sgUserCtxPool[queue_idx].completed_cb_count = 0;
   sgUserCtxPool[queue_idx].flags = flags;
   sgUserCtxPool[queue_idx].text = text;
   sgUserCtxPool[queue_idx].text_type = text_type;
   sgUserCtxPool[queue_idx].tts_path.path[0] = 0;
   sgUserCtxPool[queue_idx].retry_index = 0;
   _add_request_callback( &sgUserCtxPool[queue_idx], completed_cb, user_context );

   tts_queue_set_context( queue_idx, &sgUserCtxPool[queue_idx] );
}
コード例 #12
0
BOOL tts_register_provider( const TtsProvider* tts_provider )
{
   int i;
   BOOL result = TRUE;
   for( i = 0; i < TTS_PROVIDERS_MAX_NUM; ++i )
   {
      if ( !sgTtsProviders[i].registered )
      {
         sgTtsProviders[i] = *tts_provider; // Bit copy.
         sgTtsProviders[i].registered = TRUE;
         tts_voices_update( sgTtsProviders[i].provider_name, sgTtsProviders[i].voices_cfg );
         tts_ui_initialize();

         roadmap_log( ROADMAP_INFO, TTS_LOG_STR( "Provider %s was registered successfully" ), tts_provider->provider_name );
         break;
      }
   }
   if ( i == TTS_PROVIDERS_MAX_NUM )
   {
      roadmap_log( ROADMAP_ERROR, TTS_LOG_STR( "Cannot register more providers. Maximum: %d" ), TTS_PROVIDERS_MAX_NUM );
      result = FALSE;
   }
   return result;
}
コード例 #13
0
/*
 ******************************************************************************
 * Sets the callback for the supplied request
 */
static void _add_request_callback( TtsRequest* request, TtsRequestCompletedCb cb, void* cb_ctx )
{

   if ( request->completed_cb_count == TTS_COMPLETED_CB_MAX_NUM )
   {
      roadmap_log( ROADMAP_WARNING, TTS_LOG_STR( "Can't register more than %d callbacks for text: %s" ), TTS_COMPLETED_CB_MAX_NUM, request->text );
      return;
   }
   if ( cb )
   {
      request->completed_cb[request->completed_cb_count] = cb;
      request->completed_cb_ctx[request->completed_cb_count] = cb_ctx;
      request->completed_cb_count++;
   }

}
コード例 #14
0
void tts_register_on_voice_changed( TtsOnVoiceChangedCb cb )
{
   int i;
   for ( i = 0; i < TTS_VOICE_CHANGED_CB_MAX_NUM; ++i )
   {
      if ( sgOnVoiceChangedCBs[i] == NULL )
         break;
   }
   if ( i == TTS_VOICE_CHANGED_CB_MAX_NUM )
   {
      roadmap_log( ROADMAP_ERROR, TTS_LOG_STR( "Maximum number of callbacks (on voice changed) was exceeded" ) );
   }
   else
   {
      sgOnVoiceChangedCBs[i] = cb;
   }
}
コード例 #15
0
/*
 ******************************************************************************
 * Handles voice data update
 */
static void _voice_updated( const TtsVoice* new_voice, const TtsVoice* old_voice )
{
   if ( new_voice == NULL )
      return;

   if ( old_voice )
   {
      if ( new_voice->version > old_voice->version )
      {
         roadmap_log( ROADMAP_WARNING, TTS_LOG_STR( "Voice: %s version is incremented ( %d =>> %d ). Clearing the database. Current voice: %s" ),
               new_voice->voice_id, old_voice->version, new_voice->version, sgTtsVoiceId );
         tts_cache_clear( new_voice->voice_id );

         // Force voice change for the current voice
         if ( sgTtsVoiceId && !strcmp( sgTtsVoiceId, new_voice->voice_id ) )
         {
            _voice_changed( sgTtsVoiceId, TRUE );
         }
      }
   }
}
コード例 #16
0
BOOL tts_commit( void )
{
   TtsProviderRequest *provider_request= NULL;
   TtsRequest *tts_request;
   int i;
   const char* text;
   TtsTextList text_list = TTS_GENERIC_LIST_INITIALIZER;
   int queue_idx;
   int idx_list[TTS_QUEUE_SIZE];
   int idx_list_count;
   TtsSynthRequestParams params = TTS_SYNTH_PARMAS_INITIALIZER;

   if ( !tts_enabled() )
   {
      roadmap_log(ROADMAP_WARNING, TTS_LOG_STR( "TTS is not enabled. Cannot commit synthesize requests. Feature: %d, Provider: %d" ),
            sgTtsFeatureEnabled, ( sgActiveProvider != NULL ) );
      return FALSE;
   }

   if ( sgActiveProvider->concurrent_limit >= 0 && sgActiveRequestsCount >= sgActiveProvider->concurrent_limit )
   {
      roadmap_log( ROADMAP_WARNING, TTS_LOG_STR( "Overflow in concurrent requests for the provider. Maximum: %d" ),
                   sgActiveProvider->concurrent_limit );
      return FALSE;
   }

   idx_list_count = tts_queue_get_indexes( idx_list,
         MIN( TTS_QUEUE_SIZE, sgActiveProvider->batch_request_limit ), TTS_QUEUE_STATUS_IDLE );


   if ( idx_list_count == 0 )
   {
      roadmap_log( ROADMAP_DEBUG, TTS_LOG_STR( "There are no strings to commit." ) );
      return TRUE;
   }

   /*
    * Parameters
    */
   params.voice_id = sgTtsVoiceId;

   /*
    * Building the context.
    */
   provider_request = _provider_ctx_allocate();
   if ( provider_request == NULL )
   {
      roadmap_log( ROADMAP_ERROR, TTS_LOG_STR( "Error allocating provider context!" ) );
      return FALSE;
   }
   provider_request->start_time = roadmap_time_get_millis();
   provider_request->voice_id = sgTtsVoiceId;
   memcpy( provider_request->idx_list, idx_list, sizeof( idx_list[0] ) * idx_list_count );
   provider_request->idx_list_count = idx_list_count;

   for ( i = 0; i < idx_list_count ; ++i )
   {
      queue_idx = provider_request->idx_list[i];

      text = tts_queue_get_key( queue_idx );
      // Set status
      tts_queue_set_status( provider_request->idx_list[i], TTS_QUEUE_STATUS_COMMITTED );
      // Fill the text list
      text_list[i] = text;
      // Fill the path list
      if ( sgActiveProvider->storage_type & __tts_db_data_storage__file )
      {
         tts_request = ( TtsRequest * ) tts_queue_get_context( queue_idx );
         tts_db_generate_path( sgTtsVoiceId, &tts_request->tts_path );
         params.types_list[i] = tts_request->text_type;
         params.path_list[i] = &tts_request->tts_path;
      }
   }

   roadmap_log( ROADMAP_DEBUG, TTS_LOG_STR( "Committing list of %d tts strings." ), i );
   // Send request to the provider
   sgActiveProvider->request_cb( provider_request, text_list, &params, ( TtsSynthResponseCb ) _on_response );
   sgActiveRequestsCount++;

   return TRUE;
}
コード例 #17
0
static int _process_received( TtsProviderRequest* provider_request, TtsSynthResponseData* response_data )
{
    int queue_idx;
    BOOL apply_retry = FALSE;
    int i, j, status, matched_count = 0;
    const char* received_text, *queued_text;
    TtsRequest* tts_request;

    // Parse the response
    for ( i = 0; i < provider_request->idx_list_count; ++i )
    {

       queue_idx = provider_request->idx_list[i];

       if ( tts_queue_is_empty( queue_idx ) )
          continue;

       tts_request = tts_queue_get_context( queue_idx );
       status = tts_queue_get_status( queue_idx );
       /*
        * Test status
        */
       if ( status != TTS_QUEUE_STATUS_COMMITTED )
       {
          roadmap_log( ROADMAP_ERROR, TTS_LOG_STR( "Internal error. Current status %d differs from 'COMMITTED' (%d)" ),
                         status, TTS_QUEUE_STATUS_COMMITTED );
       }

       queued_text = tts_queue_get_key( queue_idx );

       // Look for the text in the list
       for ( j = 0; j < TTS_BATCH_REQUESTS_LIMIT; ++j )
       {
          received_text = response_data->text_list[j];
          if ( received_text && !strcmp( received_text, queued_text ) )
          {
             matched_count++;
             break;
          }
       }

       if ( j == TTS_BATCH_REQUESTS_LIMIT )
       {
          int res_status = TTS_RES_STATUS_ERROR;
          roadmap_log( ROADMAP_ERROR, TTS_LOG_STR( "The text %s was not synthesized." ), queued_text );

          apply_retry = _apply_retry( tts_request, queue_idx, &res_status );

          _run_request_callbacks( tts_request, res_status );
       }
       else
       {
          TtsData* tts_data = &response_data->tts_data[i];
          /*
           * The final result is stored in cache
           */
          tts_cache_add( provider_request->voice_id, queued_text, tts_request->text_type, sgActiveProvider->storage_type,
                   tts_data, &tts_request->tts_path );

          _run_request_callbacks( tts_request, TTS_RES_STATUS_SUCCESS );

          roadmap_log( ROADMAP_DEBUG, TTS_LOG_STR( "Successfully received audio for text: %s. Voice: %s. Path: %s" ),
                queued_text, provider_request->voice_id, tts_request->tts_path.path );

          // Deallocate the buffers if not needed
          if ( !TTS_CACHE_BUFFERS_ENABLED && tts_data->data )
          {
             free( tts_data->data );
          }
       }
       if ( !apply_retry )
       {
          tts_queue_remove( queue_idx );
          free( (char*) queued_text );
       }
    } // for i

    return matched_count;
}