Playing a sound via Jython

I have the following code, which I believe works mostly right.

[code]def playSound():
import system
from java.io import ByteArrayInputStream
from javax.sound.sampled import *

file = system.db.runScalarQuery("SELECT wav FROM sound WHERE ID = 1")
ioStream = ByteArrayInputStream(file)
stream = AudioSystem.getAudioInputStream(ioStream)
format = stream.getFormat()
if (format.getEncoding() != AudioFormat.Encoding.PCM_SIGNED):
	format = AudioFormat(AudioFormat.Encoding.PCM_SIGNED,format.getSampleRate(),format.getSampleSizeInBits()*2,format.getChannels(),format.getFrameSize()*2,format.getFrameRate(),1)
	stream = AudioSystem.getAudioInputStream(format, stream)

info = DataLine.Info(Clip, stream.getFormat(), int(stream.getFrameLength()*format.getFrameSize()))
clip  = AudioSystem.getLine(info)

clip.open(stream)
clip.start()[/code]

It is give me the following error when I try to run it in the script playground.

[code]Traceback (innermost last):
File “”, line 2, in ?
File “module:sound”, line 17, in playSound
java.lang.IllegalAccessException: Class org.python.core.PyReflectedFunction can not access a member of class com.sun.media.sound.DirectAudioDevice$DirectClip with modifiers “public”

at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java)

at org.python.core.PyMethod.__call__(PyMethod.java)

at org.python.core.PyObject.__call__(PyObject.java)

at org.python.core.PyInstance.invoke(PyInstance.java)

at org.python.pycode._pyx34.playSound$1(<module:sound>:17)

at org.python.pycode._pyx34.call_function(<module:sound>)

at org.python.core.PyTableCode.call(PyTableCode.java)

at org.python.core.PyTableCode.call(PyTableCode.java)

at org.python.core.PyFunction.__call__(PyFunction.java)

at org.python.core.PyObject.invoke(PyObject.java)

at org.python.pycode._pyx49.f$0(<script playground>:2)

at org.python.pycode._pyx49.call_function(<script playground>)

at org.python.core.PyTableCode.call(PyTableCode.java)

at org.python.core.PyCode.call(PyCode.java)

at org.python.core.Py.runCode(Py.java)

at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(Unknown Source)

at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(Unknown Source)

at com.inductiveautomation.ignition.designer.gui.tools.JythonTester.runScript(Unknown Source)

at com.inductiveautomation.ignition.designer.gui.tools.JythonTester$2.actionPerformed(Unknown Source)

at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)

at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)

at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)

at javax.swing.DefaultButtonModel.setPressed(Unknown Source)

at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)

at java.awt.Component.processMouseEvent(Unknown Source)

at javax.swing.JComponent.processMouseEvent(Unknown Source)

at java.awt.Component.processEvent(Unknown Source)

at java.awt.Container.processEvent(Unknown Source)

at java.awt.Component.dispatchEventImpl(Unknown Source)

at java.awt.Container.dispatchEventImpl(Unknown Source)

at java.awt.Component.dispatchEvent(Unknown Source)

at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)

at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)

at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)

at java.awt.Container.dispatchEventImpl(Unknown Source)

at java.awt.Window.dispatchEventImpl(Unknown Source)

at java.awt.Component.dispatchEvent(Unknown Source)

at java.awt.EventQueue.dispatchEvent(Unknown Source)

at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)

at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)

at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)

at java.awt.EventDispatchThread.pumpEvents(Unknown Source)

at java.awt.EventDispatchThread.pumpEvents(Unknown Source)

at java.awt.EventDispatchThread.run(Unknown Source)

java.lang.IllegalAccessException: java.lang.IllegalAccessException: Class org.python.core.PyReflectedFunction can not access a member of class com.sun.media.sound.DirectAudioDevice$DirectClip with modifiers “public”

at org.python.core.Py.JavaError(Py.java)
at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java)
at org.python.core.PyMethod.__call__(PyMethod.java)
at org.python.core.PyObject.__call__(PyObject.java)
at org.python.core.PyInstance.invoke(PyInstance.java)
at org.python.pycode._pyx34.playSound$1(<module:sound>:17)
at org.python.pycode._pyx34.call_function(<module:sound>)
at org.python.core.PyTableCode.call(PyTableCode.java)
at org.python.core.PyTableCode.call(PyTableCode.java)
at org.python.core.PyFunction.__call__(PyFunction.java)
at org.python.core.PyObject.invoke(PyObject.java)
at org.python.pycode._pyx49.f$0(<script playground>:2)
at org.python.pycode._pyx49.call_function(<script playground>)
at org.python.core.PyTableCode.call(PyTableCode.java)
at org.python.core.PyCode.call(PyCode.java)
at org.python.core.Py.runCode(Py.java)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(Unknown Source)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(Unknown Source)
at com.inductiveautomation.ignition.designer.gui.tools.JythonTester.runScript(Unknown Source)
at com.inductiveautomation.ignition.designer.gui.tools.JythonTester$2.actionPerformed(Unknown Source)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

Ignition v7.1.4 (b5476)
Java: Sun Microsystems Inc. 1.6.0_20
[/code]

Does anyone have any ideas. How can I access Clip as private?

Turns out this is a flaw in Jython 2.1. Since I don’t see us upgrading to a more recent version of Jython anytime soon, I’ve added a feature request for a system.util.playSound() function.

Thanks.

[quote=“Carl.Gould”]Turns out this is a flaw in Jython 2.1. Since I don’t see us upgrading to a more recent version of Jython anytime soon[/quote] I understand that changing to a newer version of Jython is a major change to Ignition but considering Jython 2.1 came out in 2001 are there more long term plans to upgrade to a newer version? If so, to what version would you upgrade?

Yes, Jython 2.1 is a bit long in the tooth. However, with the very esoteric flaw listed on this page aside, Jython 2.1 is extremely stable and performant. I’m not saying that the newer ones aren’t – I’m just saying: we don’t like to fix what ain’t broke.

That said, I’m sure we’ll upgrade to a newer version within the next few years, what version that would be? Not sure. Probably the latest stable version at the time.

Oh- and the playSoundClip function was added in 7.1.5.