1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.fourthline.cling.support.renderingcontrol;
17
18 import org.fourthline.cling.binding.annotations.UpnpAction;
19 import org.fourthline.cling.binding.annotations.UpnpInputArgument;
20 import org.fourthline.cling.binding.annotations.UpnpOutputArgument;
21 import org.fourthline.cling.binding.annotations.UpnpService;
22 import org.fourthline.cling.binding.annotations.UpnpServiceId;
23 import org.fourthline.cling.binding.annotations.UpnpServiceType;
24 import org.fourthline.cling.binding.annotations.UpnpStateVariable;
25 import org.fourthline.cling.binding.annotations.UpnpStateVariables;
26 import org.fourthline.cling.model.types.ErrorCode;
27 import org.fourthline.cling.model.types.UnsignedIntegerFourBytes;
28 import org.fourthline.cling.model.types.UnsignedIntegerTwoBytes;
29 import org.fourthline.cling.support.lastchange.LastChange;
30 import org.fourthline.cling.support.lastchange.LastChangeDelegator;
31 import org.fourthline.cling.support.model.Channel;
32 import org.fourthline.cling.support.model.PresetName;
33 import org.fourthline.cling.support.model.VolumeDBRange;
34 import org.fourthline.cling.support.renderingcontrol.lastchange.ChannelLoudness;
35 import org.fourthline.cling.support.renderingcontrol.lastchange.ChannelMute;
36 import org.fourthline.cling.support.renderingcontrol.lastchange.ChannelVolume;
37 import org.fourthline.cling.support.renderingcontrol.lastchange.ChannelVolumeDB;
38 import org.fourthline.cling.support.renderingcontrol.lastchange.RenderingControlLastChangeParser;
39 import org.fourthline.cling.support.renderingcontrol.lastchange.RenderingControlVariable;
40
41 import java.beans.PropertyChangeSupport;
42
43
44
45
46 @UpnpService(
47 serviceId = @UpnpServiceId("RenderingControl"),
48 serviceType = @UpnpServiceType(value = "RenderingControl", version = 1),
49 stringConvertibleTypes = LastChange.class
50 )
51 @UpnpStateVariables({
52 @UpnpStateVariable(
53 name = "PresetNameList",
54 sendEvents = false,
55 datatype = "string"),
56 @UpnpStateVariable(
57 name = "Mute",
58 sendEvents = false,
59 datatype = "boolean"),
60 @UpnpStateVariable(
61 name = "Volume",
62 sendEvents = false,
63 datatype = "ui2",
64 allowedValueMinimum = 0,
65 allowedValueMaximum = 100),
66 @UpnpStateVariable(
67 name = "VolumeDB",
68 sendEvents = false,
69 datatype = "i2",
70 allowedValueMinimum = -36864,
71 allowedValueMaximum = 32767),
72 @UpnpStateVariable(
73 name = "Loudness",
74 sendEvents = false,
75 datatype = "boolean"),
76 @UpnpStateVariable(
77 name = "A_ARG_TYPE_Channel",
78 sendEvents = false,
79 allowedValuesEnum = Channel.class),
80 @UpnpStateVariable(
81 name = "A_ARG_TYPE_PresetName",
82 sendEvents = false,
83 allowedValuesEnum = PresetName.class),
84 @UpnpStateVariable(
85 name = "A_ARG_TYPE_InstanceID",
86 sendEvents = false,
87 datatype = "ui4")
88
89 })
90 public abstract class AbstractAudioRenderingControl implements LastChangeDelegator {
91
92 @UpnpStateVariable(eventMaximumRateMilliseconds = 200)
93 final private LastChange lastChange;
94
95 final protected PropertyChangeSupport propertyChangeSupport;
96
97 protected AbstractAudioRenderingControl() {
98 this.propertyChangeSupport = new PropertyChangeSupport(this);
99 this.lastChange = new LastChange(new RenderingControlLastChangeParser());
100 }
101
102 protected AbstractAudioRenderingControl(LastChange lastChange) {
103 this.propertyChangeSupport = new PropertyChangeSupport(this);
104 this.lastChange = lastChange;
105 }
106
107 protected AbstractAudioRenderingControl(PropertyChangeSupport propertyChangeSupport) {
108 this.propertyChangeSupport = propertyChangeSupport;
109 this.lastChange = new LastChange(new RenderingControlLastChangeParser());
110 }
111
112 protected AbstractAudioRenderingControl(PropertyChangeSupport propertyChangeSupport, LastChange lastChange) {
113 this.propertyChangeSupport = propertyChangeSupport;
114 this.lastChange = lastChange;
115 }
116
117 @Override
118 public LastChange getLastChange() {
119 return lastChange;
120 }
121
122 @Override
123 public void appendCurrentState(LastChange lc, UnsignedIntegerFourBytes instanceId) throws Exception {
124 for (Channel channel : getCurrentChannels()) {
125 String channelString = channel.name();
126 lc.setEventedValue(
127 instanceId,
128 new RenderingControlVariable.Mute(new ChannelMute(channel, getMute(instanceId, channelString))),
129 new RenderingControlVariable.Loudness(new ChannelLoudness(channel, getLoudness(instanceId, channelString))),
130 new RenderingControlVariable.Volume(new ChannelVolume(channel, getVolume(instanceId, channelString).getValue().intValue())),
131 new RenderingControlVariable.VolumeDB(new ChannelVolumeDB(channel, getVolumeDB(instanceId, channelString))),
132 new RenderingControlVariable.PresetNameList(PresetName.FactoryDefaults.name())
133 );
134 }
135 }
136
137 public PropertyChangeSupport getPropertyChangeSupport() {
138 return propertyChangeSupport;
139 }
140
141 public static UnsignedIntegerFourBytes getDefaultInstanceID() {
142 return new UnsignedIntegerFourBytes(0);
143 }
144
145 @UpnpAction(out = @UpnpOutputArgument(name = "CurrentPresetNameList", stateVariable = "PresetNameList"))
146 public String listPresets(@UpnpInputArgument(name = "InstanceID") UnsignedIntegerFourBytes instanceId) throws RenderingControlException {
147 return PresetName.FactoryDefaults.toString();
148 }
149
150 @UpnpAction
151 public void selectPreset(@UpnpInputArgument(name = "InstanceID") UnsignedIntegerFourBytes instanceId,
152 @UpnpInputArgument(name = "PresetName") String presetName) throws RenderingControlException {
153 }
154
155 @UpnpAction(out = @UpnpOutputArgument(name = "CurrentMute", stateVariable = "Mute"))
156 public abstract boolean getMute(@UpnpInputArgument(name = "InstanceID") UnsignedIntegerFourBytes instanceId,
157 @UpnpInputArgument(name = "Channel") String channelName) throws RenderingControlException;
158
159 @UpnpAction
160 public abstract void setMute(@UpnpInputArgument(name = "InstanceID") UnsignedIntegerFourBytes instanceId,
161 @UpnpInputArgument(name = "Channel") String channelName,
162 @UpnpInputArgument(name = "DesiredMute", stateVariable = "Mute") boolean desiredMute) throws RenderingControlException;
163
164 @UpnpAction(out = @UpnpOutputArgument(name = "CurrentVolume", stateVariable = "Volume"))
165 public abstract UnsignedIntegerTwoBytes getVolume(@UpnpInputArgument(name = "InstanceID") UnsignedIntegerFourBytes instanceId,
166 @UpnpInputArgument(name = "Channel") String channelName) throws RenderingControlException;
167
168 @UpnpAction
169 public abstract void setVolume(@UpnpInputArgument(name = "InstanceID") UnsignedIntegerFourBytes instanceId,
170 @UpnpInputArgument(name = "Channel") String channelName,
171 @UpnpInputArgument(name = "DesiredVolume", stateVariable = "Volume") UnsignedIntegerTwoBytes desiredVolume) throws RenderingControlException;
172
173 @UpnpAction(out = @UpnpOutputArgument(name = "CurrentVolume", stateVariable = "VolumeDB"))
174 public Integer getVolumeDB(@UpnpInputArgument(name = "InstanceID") UnsignedIntegerFourBytes instanceId,
175 @UpnpInputArgument(name = "Channel") String channelName) throws RenderingControlException {
176 return 0;
177 }
178
179 @UpnpAction
180 public void setVolumeDB(@UpnpInputArgument(name = "InstanceID") UnsignedIntegerFourBytes instanceId,
181 @UpnpInputArgument(name = "Channel") String channelName,
182 @UpnpInputArgument(name = "DesiredVolume", stateVariable = "VolumeDB") Integer desiredVolumeDB) throws RenderingControlException {
183
184
185
186
187
188 }
189
190 @UpnpAction(out = {
191 @UpnpOutputArgument(name = "MinValue", stateVariable = "VolumeDB", getterName = "getMinValue"),
192 @UpnpOutputArgument(name = "MaxValue", stateVariable = "VolumeDB", getterName = "getMaxValue")
193 })
194 public VolumeDBRange getVolumeDBRange(@UpnpInputArgument(name = "InstanceID") UnsignedIntegerFourBytes instanceId,
195 @UpnpInputArgument(name = "Channel") String channelName) throws RenderingControlException {
196 return new VolumeDBRange(0, 0);
197 }
198
199 @UpnpAction(out = @UpnpOutputArgument(name = "CurrentLoudness", stateVariable = "Loudness"))
200 public boolean getLoudness(@UpnpInputArgument(name = "InstanceID") UnsignedIntegerFourBytes instanceId,
201 @UpnpInputArgument(name = "Channel") String channelName) throws RenderingControlException {
202 return false;
203 }
204
205 @UpnpAction
206 public void setLoudness(@UpnpInputArgument(name = "InstanceID") UnsignedIntegerFourBytes instanceId,
207 @UpnpInputArgument(name = "Channel") String channelName,
208 @UpnpInputArgument(name = "DesiredLoudness", stateVariable = "Loudness") boolean desiredLoudness) throws RenderingControlException {
209
210
211
212
213
214 }
215
216 protected abstract Channel[] getCurrentChannels();
217
218 protected Channel getChannel(String channelName) throws RenderingControlException {
219 try {
220 return Channel.valueOf(channelName);
221 } catch (IllegalArgumentException ex) {
222 throw new RenderingControlException(ErrorCode.ARGUMENT_VALUE_INVALID, "Unsupported audio channel: " + channelName);
223 }
224 }
225
226 }