test many instrument players
4 files changed, 114 insertions(+), 10 deletions(-)

M player/channel.go
M player/channelmixer.go
M player/channelsys.go
M player/player.go
M player/channel.go +72 -9
@@ 17,7 17,10 @@ type Channel struct {
 	//streamer       beep.StreamSeeker
 	// Current instrument player
 	// link ?
-	instrumentPlayer *InstrumentPlayer
+	//instrumentPlayer *InstrumentPlayer
+	// can be many
+	// can be notes pressed in gui/channels (?)
+	InstrumentPlayers []*InstrumentPlayer
 	
 	// XXX
 	// channel memory / state (?)

          
@@ 39,6 42,7 @@ func NewChannel(id int) *Channel {
 	c := &Channel{
 		id: id,
 		//num: num,
+		InstrumentPlayers: make([]*InstrumentPlayer, 0),
 	}
 
 	/*

          
@@ 57,12 61,34 @@ func (c *Channel) Num() int {
 	return c.id
 }
 
+// Has an active / channel instrument player ?
 func (c *Channel) Playing() bool {
-	if c.instrumentPlayer != nil {
-		if c.instrumentPlayer.playing {
-			return true
+	//if c.instrumentPlayer != nil {
+	if c.HasInstrumentPlayers() {
+		//if c.instrumentPlayer.playing {
+		//	return true
+		//}
+		for _, ip := range c.InstrumentPlayers {
+			if ip.playing {
+				return true
+			}
 		}
 	}
+	
+	return false
+}
+
+// Has streamers / active instrument players ?
+func (c *Channel) HasInstrumentPlayers() bool {
+	//if c.Playing() {
+	//	return true
+	//}
+
+	// XXX ?
+	if len(c.InstrumentPlayers) > 0 {
+		return true
+	}
+
 	return false
 }
 

          
@@ 70,7 96,20 @@ func (c *Channel) Playing() bool {
 func (c *Channel) AddInstrumentPlayer(ip *InstrumentPlayer) {
 	fmt.Println("Channel AddInstrumentPlayer ip:", ip)
 	
-	c.instrumentPlayer = ip
+	//c.instrumentPlayer = ip
+	c.InstrumentPlayers = append(c.InstrumentPlayers, ip)
+	
+	/*
+	// XXX finally ?
+	ip.SetChannelId(chId)
+	*/
+}
+
+func (c *Channel) RemoveAllInstrumentPlayers() {
+	fmt.Println("Channel RemoveAllInstrumentPlayers")
+	
+	c.InstrumentPlayers = nil
+	c.InstrumentPlayers = make([]*InstrumentPlayer, 0)
 }
 
 // XXX is this updating the player state ?

          
@@ 89,7 128,8 @@ func (c *Channel) RenderTick(tickSize in
 
 	// gen empty sygnal ?
 	//if c.instrumentPlayer == nil {
-	if c.instrumentPlayer == nil || c.mute {
+	//if c.instrumentPlayer == nil || c.mute {
+	if !c.HasInstrumentPlayers() || c.mute {
 		buf := Ctx.Player._renderSilence(tickSize)
 		//buf := GenEmptyBuf(lenSamples)
 				

          
@@ 113,12 153,35 @@ func (c *Channel) RenderTick(tickSize in
 	mixingVol := Ctx.Player.MixingVol
 	// XXX
 	//mixingVol := -1.0
-	ret, buf := c.instrumentPlayer.ProcessTickBuf(mixingVol)
-	_ = ret
+	//ret, buf := c.instrumentPlayer.ProcessTickBuf(mixingVol)
+	//_ = ret
 	//pp(ret)
 	//buf := c.instrumentPlayer.RenderTick(lenSamples)
+	
+	// XXX mix many
+	n := len(c.InstrumentPlayers)
+	bufs := make([][][2]float64, 0)
+	for i := 0; i < n; i++ {
+		
+		ip := c.InstrumentPlayers[i]
+		//ret, buf := c.instrumentPlayer.ProcessTickBuf(mixingVol)
+		ret, buf := ip.ProcessTickBuf(mixingVol)
+		
+		fmt.Printf("(i=%d) ret: %d\n", i, ret)
+		
+		bufs = append(bufs, buf)
+	}
+	
+	// Result buffer ?
+	// XXX
+	cm := Ctx.Player.ChannelSys.ChannelMixer
+	//cm := Ctx.Player.GetChannelMixer()
+	resBuf := cm.mixnbufs(bufs...)
+	
+	// XXX
+	buf := resBuf
 
-	fmt.Println("ret:", ret)
+	//fmt.Println("ret:", ret)
 	fmt.Println("len buf:", len(buf))
 	
 	// XXX pad signal / buffer ?

          
M player/channelmixer.go +6 -1
@@ 51,6 51,10 @@ func (cm *ChannelMixer) Init() {
 	}
 }
 
+func (cm *ChannelMixer) SetNumChannels(n int) {
+	pp(2)
+}
+
 func (cm *ChannelMixer) mixnbufs(bufs... [][2]float64) [][2]float64 {
 	//var res [][2]float64
 

          
@@ 106,7 110,8 @@ func (cm *ChannelMixer) RenderChannelTic
 	buf := ch.RenderTick(tickSize)
 		
 	// XXX update renderTickBuf
-	if true {
+	//if true {
+	if false {
 		cm.renderTickBuf[chId] = buf
 	}
 	

          
M player/channelsys.go +2 -0
@@ 47,4 47,6 @@ func (s *ChannelSys) SetNumChannels(n in
 
 	// XXX	
 	s.createChannels(n)
+	// XXX
+	//s.ChannelMixer.SetNumChannels(n)
 }

          
M player/player.go +34 -0
@@ 412,7 412,27 @@ func (p *Player) PlayCell(x *Cell, chNum
 
 		ch := p.ChannelSys.Channels[chNum]
 		_ = ch
+		
+		if ch.Playing() {
+			for _, ip := range ch.InstrumentPlayers {
+				s := ip.streamer2
+				pv(ip)
+				pv(ip.curSample)
+				//pv(s)
+				//mixer.remove(ip.streamer2)
+				__p("playing:", ch.Playing())
+				__p("has:", Xmixer.Has(s))
+				ip.Stop()
+				//__p("playing1:", ch.playing())
+				//__p("has2:", mixer.has(s))
+				//p.removeInstrumentPlayer(ip)
+				//__p("playing2:", ch.playing())
+				//__p("has:", mixer.has(s))
+				Xmixer.Remove(ip.streamer2) // XXX fixme can be buggy
+			}
+		}
 
+		/*
 		if ch.Playing() {
 			ip := ch.instrumentPlayer
 			s := ip.streamer2

          
@@ 430,6 450,7 @@ func (p *Player) PlayCell(x *Cell, chNum
 			//__p("has:", mixer.has(s))
 			Xmixer.Remove(ip.streamer2) // XXX fixme can be buggy
 		}
+		*/
 
 		pl := inst.NewPlayer()
 		pl.PlayNote(x.Note)

          
@@ 1440,11 1461,24 @@ func (p *Player) UpdateFrame() {
 	__p("updateFrame")
 	// Collect old insturment players
 	for _, ch := range p.ChannelSys.Channels {
+		if !ch.Playing() && ch.HasInstrumentPlayers() {
+			for _, ip := range ch.InstrumentPlayers {
+				p.RemoveInstrumentPlayer(ip)
+			}
+			// XXX
+			ch.RemoveAllInstrumentPlayers()
+		}
+	}
+	
+	/*
+	// Collect old insturment players
+	for _, ch := range p.ChannelSys.Channels {
 		if !ch.Playing() && ch.instrumentPlayer != nil {
 			p.RemoveInstrumentPlayer(ch.instrumentPlayer)
 			ch.instrumentPlayer = nil
 		}
 	}
+	*/
 
 	//p.UpdateOrders()