IbmWatsonVoicesTrait::extractVoiceConstraint()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 5
nc 3
nop 2
dl 0
loc 11
rs 9.2
c 0
b 0
f 0
1
<?php
2
3
namespace GinoPane\PHPolyglot\API\Implementation\TTS\IbmWatson\Voice;
4
5
use GinoPane\PHPolyglot\Exception\InvalidVoiceParametersException;
6
use GinoPane\PHPolyglot\Exception\InvalidVoiceCodeException;
7
use GinoPane\PHPolyglot\Supplemental\Language\Language;
8
use GinoPane\PHPolyglot\API\Supplemental\TTS\TtsVoiceFormat;
9
10
/**
11
 * Trait IbmWatsonVoicesTrait
12
 *
13
 * @link https://console.bluemix.net/docs/services/text-to-speech/http.html#voices
14
 *
15
 * @author Sergey <Gino Pane> Karavay
16
 */
17
trait IbmWatsonVoicesTrait
18
{
19
    /**
20
     * @return TtsVoiceFormat[]
21
     */
22
    private function getVoiceConstraints(): array
23
    {
24
        return [
25
            IbmWatsonVoicesInterface::VOICE_ALLISON => new TtsVoiceFormat(
26
                new Language(Language::CODE_ENGLISH),
27
                TtsVoiceFormat::GENDER_MALE
28
            ),
29
            IbmWatsonVoicesInterface::VOICE_BIRGIT => new TtsVoiceFormat(
30
                new Language(Language::CODE_GERMAN),
31
                TtsVoiceFormat::GENDER_FEMALE
32
            ),
33
            IbmWatsonVoicesInterface::VOICE_DIETER => new TtsVoiceFormat(
34
                new Language(Language::CODE_GERMAN),
35
                TtsVoiceFormat::GENDER_MALE
36
            ),
37
            IbmWatsonVoicesInterface::VOICE_EMI => new TtsVoiceFormat(
38
                new Language(Language::CODE_JAPANESE),
39
                TtsVoiceFormat::GENDER_FEMALE
40
            ),
41
            IbmWatsonVoicesInterface::VOICE_ENRIQUE => new TtsVoiceFormat(
42
                new Language(Language::CODE_SPANISH),
43
                TtsVoiceFormat::GENDER_MALE
44
            ),
45
            IbmWatsonVoicesInterface::VOICE_FRANCESCA => new TtsVoiceFormat(
46
                new Language(Language::CODE_ITALIAN),
47
                TtsVoiceFormat::GENDER_FEMALE
48
            ),
49
            IbmWatsonVoicesInterface::VOICE_ISABELA => new TtsVoiceFormat(
50
                new Language(Language::CODE_PORTUGUESE),
51
                TtsVoiceFormat::GENDER_FEMALE
52
            ),
53
            IbmWatsonVoicesInterface::VOICE_KATE => new TtsVoiceFormat(
54
                new Language(Language::CODE_ENGLISH),
55
                TtsVoiceFormat::GENDER_FEMALE
56
            ),
57
            IbmWatsonVoicesInterface::VOICE_LAURA => new TtsVoiceFormat(
58
                new Language(Language::CODE_SPANISH),
59
                TtsVoiceFormat::GENDER_FEMALE
60
            ),
61
            IbmWatsonVoicesInterface::VOICE_LISA => new TtsVoiceFormat(
62
                new Language(Language::CODE_ENGLISH),
63
                TtsVoiceFormat::GENDER_FEMALE
64
            ),
65
            IbmWatsonVoicesInterface::VOICE_MICHAEL => new TtsVoiceFormat(
66
                new Language(Language::CODE_ENGLISH),
67
                TtsVoiceFormat::GENDER_MALE
68
            ),
69
            IbmWatsonVoicesInterface::VOICE_RENEE => new TtsVoiceFormat(
70
                new Language(Language::CODE_FRENCH),
71
                TtsVoiceFormat::GENDER_FEMALE
72
            ),
73
            IbmWatsonVoicesInterface::VOICE_SOFIA_LA => new TtsVoiceFormat(
74
                new Language(Language::CODE_SPANISH),
75
                TtsVoiceFormat::GENDER_FEMALE
76
            ),
77
            IbmWatsonVoicesInterface::VOICE_SOFIA_US => new TtsVoiceFormat(
78
                new Language(Language::CODE_SPANISH),
79
                TtsVoiceFormat::GENDER_FEMALE
80
            ),
81
        ];
82
    }
83
84
    /**
85
     * @param Language $language
86
     * @param array    $additionalData
87
     *
88
     * @throws InvalidVoiceCodeException
89
     * @throws InvalidVoiceParametersException
90
     *
91
     * @return string
92
     */
93
    public function getVoiceParameter(Language $language, array $additionalData = []): string
94
    {
95
        $voiceConstraints = $this->getVoiceConstraints();
96
97
        /** @var string $voice */
98
        /** @var TtsVoiceFormat $voiceConstraint */
99
        list($voice, $voiceConstraint) = $this->extractVoiceConstraint($voiceConstraints, $additionalData);
100
101
        if (!empty($voiceConstraint)) {
102
            if ($voiceConstraint->getLanguage()->getCode() == $language->getCode()) {
103
                return $voice;
104
            }
105
106
            throw new InvalidVoiceParametersException(
107
                sprintf(
108
                    "The requested language \"%s\" is not compatible with the requested voice \"%s\"",
109
                    $language, //@codeCoverageIgnore
110
                    $voice
111
                )
112
            );
113
        }
114
115
        $languageCode = $language->getCode();
116
        $genderCode = $additionalData['gender'] ?? null;
117
118
        $voiceConstraints = array_filter(
119
            $voiceConstraints, //@codeCoverageIgnore
120
            function (TtsVoiceFormat $item) use ($languageCode, $genderCode) {
121
                return
122
                    ($item->getLanguage()->getCode() == $languageCode) &&
123
                    (!empty($genderCode) ? $item->getGender() == $genderCode : true);
124
            }
125
        );
126
127
        if (empty($voiceConstraints)) {
128
            throw new InvalidVoiceParametersException(
129
                sprintf(
130
                    "Couldn't find the voice for requested language \"%s\" and gender \"%s\"",
131
                    $language, //@codeCoverageIgnore
132
                    $genderCode ?? 'no gender'
133
                )
134
            );
135
        }
136
137
        /** @var string[] $voices */
138
        $voices = array_keys($voiceConstraints);
139
        $voice = array_shift($voices);
140
141
        return $voice;
142
    }
143
144
    /**
145
     * @param       $voiceConstraints
146
     * @param array $additionalData
147
     *
148
     * @throws InvalidVoiceCodeException
149
     *
150
     * @return array
151
     */
152
    private function extractVoiceConstraint(array $voiceConstraints, array $additionalData): array
153
    {
154
        if (isset($additionalData['voice']) && $voice = $additionalData['voice']) {
155
            if (empty($voiceConstraints[$voice])) {
156
                throw new InvalidVoiceCodeException($voice);
157
            }
158
159
            $voiceConstraint = $voiceConstraints[$voice];
160
        }
161
162
        return [$voice ?? null, $voiceConstraint ?? null];
163
    }
164
}
165