1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AudioCodec {
	Opus,
	Vorbis
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AudioEncoding {
	Pcm,
	ALaw,
	MuLaw
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AudioChannels {
	/// Single channel (mono) audio.
	Mono,
	/// 2 channel (stereo) audio.
	Stereo
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AudioContainer {
	/// Containerless audio, only used with PCM, A-law, and mu-law encodings.
	Raw,
	/// RIFF format, aka .WAV lossless audio.
	Riff(AudioEncoding),
	/// MP3 format audio.
	Mp3,
	/// OGG format audio.
	Ogg(AudioCodec),
	/// WEBM format audio.
	Webm(AudioCodec)
}

/// Struct used for negotiating an audio format supported by both the application and the speech synthesiser.
#[derive(Debug, Default, Clone)]
pub struct AudioFormatPreference {
	pub sample_rates: Option<Vec<u32>>,
	pub channels: Option<Vec<AudioChannels>>,
	pub bitrates: Option<Vec<u16>>,
	pub containers: Option<Vec<AudioContainer>>
}

impl AudioFormatPreference {
	pub fn with_prefer_sample_rates(mut self, pref: impl IntoIterator<Item = u32>) -> Self {
		match self.sample_rates.as_mut() {
			None => self.sample_rates = Some(pref.into_iter().collect()),
			Some(sample_rates) => sample_rates.extend(pref)
		}
		self
	}

	pub fn with_prefer_channels(mut self, pref: impl IntoIterator<Item = AudioChannels>) -> Self {
		match self.channels.as_mut() {
			None => self.channels = Some(pref.into_iter().collect()),
			Some(channels) => channels.extend(pref)
		}
		self
	}

	pub fn with_prefer_bitrates(mut self, pref: impl IntoIterator<Item = u16>) -> Self {
		match self.bitrates.as_mut() {
			None => self.bitrates = Some(pref.into_iter().collect()),
			Some(bitrates) => bitrates.extend(pref)
		}
		self
	}

	pub fn with_prefer_containers(mut self, pref: impl IntoIterator<Item = AudioContainer>) -> Self {
		match self.containers.as_mut() {
			None => self.containers = Some(pref.into_iter().collect()),
			Some(containers) => containers.extend(pref)
		}
		self
	}
}

#[derive(Debug, Clone)]
pub struct AudioFormat {
	name: Option<Box<str>>,
	sample_rate: u32,
	channels: AudioChannels,
	bitrate: Option<u16>,
	container: AudioContainer
}

impl AudioFormat {
	pub fn new(sample_rate: u32, channels: AudioChannels, bitrate: Option<u16>, container: AudioContainer) -> Self {
		AudioFormat {
			name: None,
			sample_rate,
			channels,
			bitrate,
			container
		}
	}

	pub fn new_named(name: impl Into<Box<str>>, sample_rate: u32, channels: AudioChannels, bitrate: Option<u16>, container: AudioContainer) -> Self {
		AudioFormat {
			name: Some(name.into()),
			sample_rate,
			channels,
			bitrate,
			container
		}
	}

	pub fn name(&self) -> Option<&str> {
		self.name.as_deref()
	}

	pub fn sample_rate(&self) -> u32 {
		self.sample_rate
	}

	pub fn channels(&self) -> AudioChannels {
		self.channels
	}

	pub fn bitrate(&self) -> Option<u16> {
		self.bitrate
	}

	pub fn container(&self) -> AudioContainer {
		self.container
	}
}