1   package org.daisy.pipeline.tts;
2   
3   import java.util.HashMap;
4   import java.util.Map;
5   
6   import cz.vutbr.web.css.CSSProperty;
7   import cz.vutbr.web.css.CSSProperty.SpeechRate;
8   import cz.vutbr.web.css.Declaration;
9   import cz.vutbr.web.css.SupportedCSS;
10  import cz.vutbr.web.css.Term;
11  import cz.vutbr.web.css.TermIdent;
12  import cz.vutbr.web.css.TermInteger;
13  import cz.vutbr.web.css.TermPercent;
14  import cz.vutbr.web.domassign.DeclarationTransformer;
15  import cz.vutbr.web.domassign.SupportedCSS21;
16  
17  import org.daisy.braille.css.BrailleCSSParserFactory; // BrailleCSSParserFactory can be used for regular CSS too
18  import org.daisy.common.properties.Properties;
19  import org.daisy.common.properties.Properties.Property;
20  import org.daisy.pipeline.css.speech.SpeechDeclarationTransformer;
21  
22  public class DefaultSpeechRate {
23  
24  	private static final Property SPEECH_RATE = Properties.getProperty("org.daisy.pipeline.tts.speech-rate",
25  	                                                                   true,
26  	                                                                   "Default speaking rate",
27  	                                                                   false,
28  	                                                                   "100%");
29  
30  	private static final SupportedCSS speechCSS = SupportedCSS21.getInstance();
31  	private static final DeclarationTransformer declarationTransformer = new SpeechDeclarationTransformer();
32  	private static final BrailleCSSParserFactory parserFactory = new BrailleCSSParserFactory();
33  
34  	public DefaultSpeechRate() {}
35  
36  	/**
37  	 * Get current value of {@code org.daisy.pipeline.tts.speech-rate} property as a relative value,
38  	 * with 1.0 corresponding with the normal speaking rate of 200 words per minute.
39  	 */
40  	public float getValue(Map<String,String> properties) {
41  		Iterable<? extends Declaration> declarations
42  			= parserFactory.parseSimpleInlineStyle("speech-rate: " + SPEECH_RATE.getValue(properties));
43  		if (declarations != null)
44  			for (Declaration d : declarations) {
45  				Map<String,CSSProperty> props = new HashMap<>();
46  				Map<String,Term<?>> terms = new HashMap<>();
47  				if (declarationTransformer.parseDeclaration(d, props, terms))
48  					for (String name: props.keySet()) {
49  						CSSProperty p = props.get(name);
50  						if (p instanceof SpeechRate)
51  							switch ((SpeechRate)p) {
52  							case X_SLOW:
53  								return 0.4f; // 80 words per minute
54  							case SLOW:
55  								return 0.6f; // 120 words per minute
56  							case MEDIUM:
57  								return 1.0f; // 200 words per minute
58  							case FAST:
59  								return 1.5f; // 300 words per minute
60  							case X_FAST:
61  								return 2.5f; // 500 words per minute
62  							case number:
63  								Term<?> t = terms.get(name);
64  								if (t != null)
65  									if (t instanceof TermPercent)
66  										return ((TermPercent)t).getValue() / 100;
67  									else if (t instanceof TermInteger) // words per minute
68  										return ((TermInteger)t).getValue() / 200;
69  								break;
70  							case FASTER:
71  							case SLOWER:
72  							case INHERIT:
73  							case INITIAL:
74  							default:
75  							}
76  					}
77  			}
78  		return 1.0f;
79  	}
80  }