array( 'name' => 'Eleven v4', 'description' => __( 'Latest generation, expressive narration, 90+ languages', 'accessibility-audio-tts-text-to-speech-for-articles' ), 'max_characters' => 10000, 'family' => 'expressive', 'legacy' => false ), 'eleven_v3' => array( 'name' => 'Eleven v3', 'description' => __( 'Expressive narration and audio tags, 70+ languages', 'accessibility-audio-tts-text-to-speech-for-articles' ), 'max_characters' => 5000, 'family' => 'v3', 'legacy' => false ), 'eleven_multilingual_v2' => array( 'name' => 'Eleven Multilingual v2', 'description' => __( 'Stable long-form narration, 29 languages', 'accessibility-audio-tts-text-to-speech-for-articles' ), 'max_characters' => 10000, 'family' => 'standard', 'legacy' => false ), 'eleven_flash_v2_5' => array( 'name' => 'Eleven Flash v2.5', 'description' => __( 'Fast multilingual speech, 32 languages', 'accessibility-audio-tts-text-to-speech-for-articles' ), 'max_characters' => 40000, 'family' => 'flash', 'legacy' => false ), 'eleven_flash_v2' => array( 'name' => 'Eleven Flash v2', 'description' => __( 'Fast speech, English only', 'accessibility-audio-tts-text-to-speech-for-articles' ), 'max_characters' => 30000, 'family' => 'flash', 'legacy' => false ), 'eleven_turbo_v2_5' => array( 'name' => 'Eleven Turbo v2.5', 'description' => __( 'Legacy multilingual model; existing selections are preserved', 'accessibility-audio-tts-text-to-speech-for-articles' ), 'max_characters' => 40000, 'family' => 'flash', 'legacy' => true ), 'eleven_turbo_v2' => array( 'name' => 'Eleven Turbo v2', 'description' => __( 'Legacy English model; existing selections are preserved', 'accessibility-audio-tts-text-to-speech-for-articles' ), 'max_characters' => 30000, 'family' => 'flash', 'legacy' => true ), 'eleven_multilingual_v1' => array( 'name' => 'Eleven Multilingual v1', 'description' => __( 'Previous generation multilingual model', 'accessibility-audio-tts-text-to-speech-for-articles' ), 'max_characters' => 10000, 'family' => 'standard', 'legacy' => true ), 'eleven_monolingual_v1' => array( 'name' => 'Eleven Monolingual v1', 'description' => __( 'Previous generation English model', 'accessibility-audio-tts-text-to-speech-for-articles' ), 'max_characters' => 2500, 'family' => 'standard', 'legacy' => true ), ); } public static function ids(): array { return array_keys( self::all() ); } public static function is_supported( $model ): bool { return is_string( $model ) && isset( self::all()[ $model ] ); } public static function get( string $model ): array { $models = self::all(); if ( ! isset( $models[ $model ] ) ) { throw new \InvalidArgumentException( __( 'This speech model is not supported by this plugin.', 'accessibility-audio-tts-text-to-speech-for-articles' ) ); } return $models[ $model ]; } public static function for_ui(): array { $items = array(); foreach ( self::all() as $value => $model ) { $items[] = array( 'value' => $value, 'name' => $model['name'], 'description' => $model['description'], 'recommended' => self::RECOMMENDED_MODEL === $value, 'legacy' => $model['legacy'], 'maxCharacters' => $model['max_characters'], 'costEstimateAvailable' => ! in_array( $value, array( 'eleven_v4', 'eleven_v3' ), true ) ); } return $items; } /** Only send controls supported by the selected model's generation family. */ public static function voice_settings( string $model, array $overrides = array() ): array { $capabilities = self::get( $model ); $defaults = array( 'stability' => 0.5, 'similarity_boost' => 0.75, 'style' => 0.0, 'use_speaker_boost' => true ); if ( 'expressive' === $capabilities['family'] ) { $defaults = array_intersect_key( $defaults, array_flip( array( 'stability', 'similarity_boost' ) ) ); } if ( 'v3' === $capabilities['family'] ) { $defaults = array( 'stability' => 0.5 ); } $settings = array_replace( $defaults, array_intersect_key( $overrides, $defaults ) ); foreach ( $settings as $key => $value ) { $settings[ $key ] = 'use_speaker_boost' === $key ? (bool) $value : max( 0.0, min( 1.0, (float) $value ) ); } return $settings; } public static function supports_continuity( string $model ): bool { return ! in_array( self::get( $model )['family'], array( 'expressive', 'v3' ), true ); } public static function supports_ssml( string $model ): bool { return ! in_array( self::get( $model )['family'], array( 'expressive', 'v3' ), true ); } public static function normalization( string $model ): string { return 'standard' === self::get( $model )['family'] ? 'on' : 'auto'; } }