1
- use serde:: { Deserialize , Serialize } ;
1
+ use std:: fmt;
2
+
3
+ use duplicate:: duplicate_item;
4
+ use serde:: { de, Deserialize , Deserializer , Serialize , Serializer } ;
2
5
3
6
/* 各フィールドのjsonフィールド名はsnake_caseとする*/
4
7
@@ -64,6 +67,21 @@ pub struct AudioQuery {
64
67
pub output_sampling_rate : u32 ,
65
68
/// 音声データをステレオ出力するか否か。
66
69
pub output_stereo : bool ,
70
+ // TODO: VOICEVOX/voicevox_engine#1308 を実装する
71
+ /// 句読点などの無音時間。`null`のときは無視される。デフォルト値は`null`。
72
+ #[ serde(
73
+ default ,
74
+ deserialize_with = "deserialize_pause_length" ,
75
+ serialize_with = "serialize_pause_length"
76
+ ) ]
77
+ pub pause_length : ( ) ,
78
+ /// 読点などの無音時間(倍率)。デフォルト値は`1`。
79
+ #[ serde(
80
+ default ,
81
+ deserialize_with = "deserialize_pause_length_scale" ,
82
+ serialize_with = "serialize_pause_length_scale"
83
+ ) ]
84
+ pub pause_length_scale : ( ) ,
67
85
/// \[読み取り専用\] AquesTalk風記法。
68
86
///
69
87
/// [`Synthesizer::audio_query`]が返すもののみ`Some`となる。入力としてのAudioQueryでは無視され
@@ -73,6 +91,87 @@ pub struct AudioQuery {
73
91
pub kana : Option < String > ,
74
92
}
75
93
94
+ fn deserialize_pause_length < ' de , D > ( deserializer : D ) -> Result < ( ) , D :: Error >
95
+ where
96
+ D : Deserializer < ' de > ,
97
+ {
98
+ return deserializer. deserialize_any ( Visitor ) ;
99
+
100
+ struct Visitor ;
101
+
102
+ impl < ' de > de:: Visitor < ' de > for Visitor {
103
+ type Value = ( ) ;
104
+
105
+ fn expecting ( & self , formatter : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
106
+ formatter. write_str ( "`null`" )
107
+ }
108
+
109
+ #[ duplicate_item(
110
+ method T ;
111
+ [ visit_i64 ] [ i64 ] ;
112
+ [ visit_u64 ] [ u64 ] ;
113
+ [ visit_f64 ] [ f64 ] ;
114
+ ) ]
115
+ fn method < E > ( self , _: T ) -> Result < Self :: Value , E >
116
+ where
117
+ E : de:: Error ,
118
+ {
119
+ Err ( E :: custom ( "currently `pause_length` must be `null`" ) )
120
+ }
121
+
122
+ fn visit_unit < E > ( self ) -> Result < Self :: Value , E > {
123
+ Ok ( ( ) )
124
+ }
125
+ }
126
+ }
127
+
128
+ fn serialize_pause_length < S > ( _: & ( ) , serializer : S ) -> Result < S :: Ok , S :: Error >
129
+ where
130
+ S : Serializer ,
131
+ {
132
+ serializer. serialize_unit ( )
133
+ }
134
+
135
+ fn deserialize_pause_length_scale < ' de , D > ( deserializer : D ) -> Result < ( ) , D :: Error >
136
+ where
137
+ D : Deserializer < ' de > ,
138
+ {
139
+ return deserializer. deserialize_any ( Visitor ) ;
140
+
141
+ struct Visitor ;
142
+
143
+ impl < ' de > de:: Visitor < ' de > for Visitor {
144
+ type Value = ( ) ;
145
+
146
+ fn expecting ( & self , formatter : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
147
+ formatter. write_str ( "`1.`" )
148
+ }
149
+
150
+ #[ duplicate_item(
151
+ method T ONE ;
152
+ [ visit_i64 ] [ i64 ] [ 1 ] ;
153
+ [ visit_u64 ] [ u64 ] [ 1 ] ;
154
+ [ visit_f64 ] [ f64 ] [ 1. ] ;
155
+ ) ]
156
+ fn method < E > ( self , v : T ) -> Result < Self :: Value , E >
157
+ where
158
+ E : de:: Error ,
159
+ {
160
+ if v != ONE {
161
+ return Err ( E :: custom ( "currently `pause_length_scale` must be `1.`" ) ) ;
162
+ }
163
+ Ok ( ( ) )
164
+ }
165
+ }
166
+ }
167
+
168
+ fn serialize_pause_length_scale < S > ( _: & ( ) , serializer : S ) -> Result < S :: Ok , S :: Error >
169
+ where
170
+ S : Serializer ,
171
+ {
172
+ ( 1. ) . serialize ( serializer)
173
+ }
174
+
76
175
impl AudioQuery {
77
176
pub ( crate ) fn with_kana ( self , kana : Option < String > ) -> Self {
78
177
Self { kana, ..self }
@@ -99,6 +198,8 @@ mod tests {
99
198
post_phoneme_length : 0.0 ,
100
199
output_sampling_rate : 0 ,
101
200
output_stereo : false ,
201
+ pause_length : ( ) ,
202
+ pause_length_scale : ( ) ,
102
203
kana : None ,
103
204
} ;
104
205
let val = serde_json:: to_value ( audio_query_model) . unwrap ( ) ;
@@ -152,4 +253,42 @@ mod tests {
152
253
} ) ) ?;
153
254
Ok ( ( ) )
154
255
}
256
+
257
+ // TODO: 型的に自明になったらこのテストは削除する
258
+ #[ rstest]
259
+ fn it_denies_non_null_for_pause_length ( ) {
260
+ serde_json:: from_value :: < AudioQuery > ( json ! ( {
261
+ "accent_phrases" : [ ] ,
262
+ "speed_scale" : 1.0 ,
263
+ "pitch_scale" : 0.0 ,
264
+ "intonation_scale" : 1.0 ,
265
+ "volume_scale" : 1.0 ,
266
+ "pre_phoneme_length" : 0.1 ,
267
+ "post_phoneme_length" : 0.1 ,
268
+ "output_sampling_rate" : 24000 ,
269
+ "output_stereo" : false ,
270
+ "pause_length" : "aaaaa"
271
+ } ) )
272
+ . map ( |_| ( ) )
273
+ . unwrap_err ( ) ;
274
+ }
275
+
276
+ // TODO: 型的に自明になったらこのテストは削除する
277
+ #[ rstest]
278
+ fn it_denies_non_float_for_pause_length_scale ( ) {
279
+ serde_json:: from_value :: < AudioQuery > ( json ! ( {
280
+ "accent_phrases" : [ ] ,
281
+ "speed_scale" : 1.0 ,
282
+ "pitch_scale" : 0.0 ,
283
+ "intonation_scale" : 1.0 ,
284
+ "volume_scale" : 1.0 ,
285
+ "pre_phoneme_length" : 0.1 ,
286
+ "post_phoneme_length" : 0.1 ,
287
+ "output_sampling_rate" : 24000 ,
288
+ "output_stereo" : false ,
289
+ "pause_length_scale" : "aaaaa" ,
290
+ } ) )
291
+ . map ( |_| ( ) )
292
+ . unwrap_err ( ) ;
293
+ }
155
294
}
0 commit comments