All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
de.sciss.proc.gui.impl.ScopeBaseImpl.scala Maven / Gradle / Ivy
/*
* ScopeBaseImpl.scala
* (SoundProcesses)
*
* Copyright (c) 2010-2024 Hanns Holger Rutz. All rights reserved.
*
* This software is published under the GNU Affero General Public License v3+
*
*
* For further information, please contact Hanns Holger Rutz at
* [email protected]
*/
package de.sciss.proc.gui.impl
import de.sciss.lucre.Txn.peer
import de.sciss.lucre.swing.LucreSwing.{deferTx, requireEDT}
import de.sciss.lucre.synth.{AudioBus, Buffer, Bus, ControlBus, Group, RT, Server, Synth}
import de.sciss.proc.gui.ScopeBase
import de.sciss.synth.swing.j.JScopeView.Config
import de.sciss.synth.{AddAction, SynthGraph, addToTail, AudioBus => SAudioBus, Bus => SBus, ControlBus => SControlBus}
import javax.swing.JComponent
import scala.concurrent.stm.Ref
abstract class ScopeBaseImpl[P <: ScopePanelBaseImpl[P]](server: Server) extends ScopeBase
with AudioBus .User
with ControlBus .User {
private[this] val busRef = Ref.make[Bus]()
private[this] val tgtRef = Ref.make[Group]()
private[this] val aaRef = Ref[AddAction](addToTail)
private[this] val synRef = Ref(Option.empty[Synth])
private[this] var _panel: JComponent with P = _
protected def mkPanel(): JComponent with P
protected def panel: JComponent with P = _panel
def initGUI(channelStyle: Int, bufSize: Int, xZoom: Double, yZoom: Double, logAmp: Boolean, logAmpMin: Double): Unit = {
requireEDT()
val p = mkPanel() // new PanelImpl(this)
p.channelStyle = channelStyle
p.bufferSize = bufSize
p.xZoom = xZoom.toFloat
p.yZoom = yZoom.toFloat
p.logAmp = logAmp
p.logAmpMin = logAmpMin.toFloat
_panel = p
}
def target(implicit tx: RT): Group = {
val _bus = bus
val _target = tgtRef()
if (_target != null || _bus == null) _target else _bus.server.rootNode
}
def target_=(value: Group)(implicit tx: RT): Unit = {
// val old = target
tgtRef() = value
// if (value != old) {
// }
}
def addAction(implicit tx: RT): AddAction = aaRef()
def addAction_=(value: AddAction)(implicit tx: RT): Unit =
aaRef() = value
def bus(implicit tx: RT): Bus = busRef()
def bus_=(b: Bus)(implicit tx: RT): Unit = {
val old = busRef.swap(b)
if (old != null) old match {
case ab: AudioBus => ab.removeReader(this)
case cb: ControlBus => cb.removeReader(this)
}
if (b != null) {
require (b.server == server)
b match {
case ab: AudioBus => ab.addReader(this)
case cb: ControlBus => cb.addReader(this)
}
}
}
def start()(implicit tx: RT): Unit =
deferTx {
component.start()
}
def stop()(implicit tx: RT): Unit =
deferTx {
component.stop()
}
def dispose()(implicit tx: RT): Unit = {
bus = null
synRef.swap(None).foreach(_.free())
deferTx {
component.dispose()
}
}
def busChanged(peer: SAudioBus, isDummy: Boolean)(implicit tx: RT): Unit = if (!isDummy) {
deferTx {
_panel.bus = peer
}
}
def busChanged(peer: SControlBus)(implicit tx: RT): Unit = {
deferTx {
_panel.bus = peer
}
}
def mkBusSynthTx(_bus: SBus)(implicit tx: RT): Unit = {
val numChannels = _bus.numChannels
val oldSyn = synRef()
if (numChannels > 0) {
val gr = SynthGraph {
_panel.mkSynthGraphImpl(_bus)
}
val useFrames = _panel.bufferSize
val s = _bus.server
// this is a bit tricky; we don't know the buffer and node at this point, so we have to copy the object
val cfg0 = Config.default(s, bufId = -1, useFrames = useFrames, numChannels = numChannels, nodeId = -1)
val bufFrames = cfg0.bufFrames
val b = Buffer(server)(numFrames = bufFrames, numChannels = numChannels)
val trFreq = Config.defaultTrigFreq(s)
val syn = Synth.play(gr, nameHint = Some("scope"))(target = target,
args = List("out" -> _bus.index, "buf" -> b.id, "freq" -> trFreq),
addAction = addAction, dependencies = b :: Nil)
val cfg = cfg0.copy(bufId = b.id, nodeId = syn.peer.id)
syn.onEndTxn { implicit tx => b.dispose() }
synRef() = Some(syn)
deferTx {
_panel.config = cfg
}
} else {
deferTx {
_panel.config = Config.Empty
}
}
oldSyn.foreach(_.dispose())
}
}