// Gen generates a buffer using a routine. // A runtime panic will occur if routine is not one of the // BufferRoutine constants. func (self *Buffer) Gen(routine string, flags int, args ...float32) error { if err := checkBufferRoutine(routine); err != nil { return err } if err := checkBufferGenFlags(flags); err != nil { return err } pat := bufferGenAddress gen, err := osc.NewMessage(pat) if err != nil { return err } if err := gen.WriteInt32(self.Num); err != nil { return err } if err := gen.WriteString(routine); err != nil { return err } if err := gen.WriteInt32(int32(flags)); err != nil { return err } for _, arg := range args { if err := gen.WriteFloat32(arg); err != nil { return err } } if err := self.client.oscConn.Send(gen); err != nil { return err } var done *osc.Message select { case done = <-self.client.doneChan: case err = <-self.client.oscErrChan: return err } if done.CountArguments() != 2 { return errors.New("expected two arguments to /done message") } _, err = done.ReadString() if err != nil { return err } bufnum, err := done.ReadInt32() if err != nil { return err } // TODO: // Don't error if we get a done message for a different buffer. // We should probably requeue this particular done message on doneChan. if bufnum != self.Num { m := "expected done message for buffer %d, but got one for buffer %d" return fmt.Errorf(m, self.Num, bufnum) } return nil }
// AllocBuffer allocates a buffer on the server func (self *Client) AllocBuffer(frames, channels int) (*Buffer, error) { buf := newBuffer(self) pat := bufferAllocAddress alloc, err := osc.NewMessage(pat) if err != nil { return nil, err } if err := alloc.WriteInt32(buf.Num); err != nil { return nil, err } if err := alloc.WriteInt32(int32(frames)); err != nil { return nil, err } if err := alloc.WriteInt32(int32(channels)); err != nil { return nil, err } if err := self.oscConn.Send(alloc); err != nil { return nil, err } var done *osc.Message select { case done = <-self.doneChan: break case err = <-self.oscErrChan: return nil, err } // error if this message was not an ack of the synthdef if done.CountArguments() != 2 { return nil, fmt.Errorf("expected two arguments to /done message") } addr, err := done.ReadString() if err != nil { return nil, err } if addr != pat { return nil, fmt.Errorf("expected first argument to be %s but got %s", pat, addr) } bufnum, err := done.ReadInt32() if err != nil { return nil, err } // TODO: // Don't error if we get a done message for a different buffer. // We should probably requeue this particular done message on doneChan. if bufnum != buf.Num { m := "expected done message for buffer %d, but got one for buffer %d" return nil, fmt.Errorf(m, buf.Num, bufnum) } return buf, nil }
// ReadBuffer tells the server to read an audio file and // load it into a buffer func (self *Client) ReadBuffer(path string, num int32) (*Buffer, error) { allocRead, err := osc.NewMessage(bufferReadAddress) if err != nil { return nil, err } buf := newReadBuffer(path, num, self) if err := allocRead.WriteInt32(buf.Num); err != nil { return nil, err } if err := allocRead.WriteString(path); err != nil { return nil, err } if err := self.oscConn.Send(allocRead); err != nil { return nil, err } var done *osc.Message select { case done = <-self.doneChan: case err = <-self.oscErrChan: return nil, err } // error if this message was not an ack of the buffer read if done.CountArguments() != 2 { return nil, fmt.Errorf("expected two arguments to /done message") } addr, err := done.ReadString() if err != nil { return nil, err } if addr != bufferReadAddress { return nil, fmt.Errorf("expected first argument to be %s but got %s", bufferReadAddress, addr) } bufnum, err := done.ReadInt32() if err != nil { return nil, err } // TODO: // Don't error if we get a done message for a different buffer. // We should probably requeue this particular done message on doneChan. if bufnum != buf.Num { m := "expected done message for buffer %d, but got one for buffer %d" return nil, fmt.Errorf(m, buf.Num, bufnum) } return buf, nil }
// SendDef sends a synthdef to scsynth. // This method blocks until a /done message is received // indicating that the synthdef was loaded func (self *Client) SendDef(def *Synthdef) error { msg, err := osc.NewMessage(synthdefReceiveAddress) if err != nil { return err } db, err := def.Bytes() if err != nil { return err } if err := msg.WriteBlob(db); err != nil { return err } if err := self.oscConn.Send(msg); err != nil { return err } var done *osc.Message select { case done = <-self.doneChan: goto ParseMessage case err = <-self.oscErrChan: return err } ParseMessage: // error if this message was not an ack of the synthdef errmsg := "expected /done with /d_recv argument" if done.CountArguments() != 1 { return fmt.Errorf(errmsg) } addr, err := done.ReadString() if err != nil { return err } if addr != synthdefReceiveAddress { return errors.New(errmsg) } return nil }