Ejemplo n.º 1
0
// InitializeSound Initializes sound
func InitializeSound(numKeys int) {
	var i float64
	data = []byte{}
	for i = 0; i < 100000; i = i + 8 {
		data = append(data, byte(128+127*math.Sin(i)))
	}

	err := al.OpenDevice()
	if err != nil {
		fmt.Println(err)
	}

	sources = al.GenSources(numKeys)
	buffers = al.GenBuffers(numKeys)
	secSources = al.GenSources(numKeys)
	secBuffers = al.GenBuffers(numKeys)

	for j := 0; j < numKeys; j++ {
		buffers[j].BufferData(al.FormatMono8, data, int32(100*(numKeys-j)))
		secBuffers[j].BufferData(al.FormatMono8, data, 2*int32(100*(numKeys-j)))
		sources[j].QueueBuffers(buffers[j : j+1]...)
		secSources[j].QueueBuffers(buffers[j : j+1]...)
	}

}
Ejemplo n.º 2
0
func (c *Context) Play() {
	c.Lock()
	defer c.Unlock()
	n := c.source.BuffersProcessed()
	if n > 0 {
		rm, split := c.queue[:n], c.queue[n:]
		c.queue = split
		c.source.UnqueueBuffers(rm...)
		al.DeleteBuffers(rm...)
	}
	for len(c.queue) < QUEUE {
		b := al.GenBuffers(1)
		buf := make([]byte, NS*CZ)
		for n := 0; n < NS*CZ; n += CZ {
			v := int16(float32(32767) * c.oscilator())
			binary.LittleEndian.PutUint16(buf[n:n+2], uint16(v))
		}
		b[0].BufferData(Fmt, buf, SampleRate)
		c.source.QueueBuffers(b...)
		c.queue = append(c.queue, b...)
	}
	if c.source.State() != al.Playing {
		al.PlaySources(c.source)
	}
}
Ejemplo n.º 3
0
func NewPlayer(sampleRate, channelNum, bytesPerSample int) (*Player, error) {
	var p *Player
	if err := al.OpenDevice(); err != nil {
		return nil, fmt.Errorf("driver: OpenAL initialization failed: %v", err)
	}
	s := al.GenSources(1)
	if e := al.Error(); e != 0 {
		return nil, fmt.Errorf("driver: al.GenSources error: %d", e)
	}
	p = &Player{
		alSource:   s[0],
		alBuffers:  []al.Buffer{},
		sampleRate: sampleRate,
		alFormat:   alFormat(channelNum, bytesPerSample),
	}
	runtime.SetFinalizer(p, (*Player).Close)

	bs := al.GenBuffers(maxBufferNum)
	const bufferSize = 1024
	emptyBytes := make([]byte, bufferSize)
	for _, b := range bs {
		// Note that the third argument of only the first buffer is used.
		b.BufferData(p.alFormat, emptyBytes, int32(p.sampleRate))
		p.alSource.QueueBuffers(b)
	}
	al.PlaySources(p.alSource)
	return p, nil
}
Ejemplo n.º 4
0
// newPianoKey creates a PianoKey with color and sound.
func newPianoKey(glctx gl.Context, keyColor util.RGBColor, note util.KeyNote) *PianoKey {
	key := new(PianoKey)
	key.keyColor = keyColor
	// Create buffer
	key.glBuf = glctx.CreateBuffer()
	glctx.BindBuffer(gl.ARRAY_BUFFER, key.glBuf)
	// Generate sound
	_ = al.OpenDevice()
	key.soundBuffers = al.GenBuffers(1)
	key.soundSources = al.GenSources(1)
	key.soundBuffers[0].BufferData(al.FormatStereo8, audio.GenSound(note), audio.SampleRate)
	key.soundSources[0].QueueBuffers(key.soundBuffers)
	return key
}
Ejemplo n.º 5
0
func (p *Player) prepare(offset int64, force bool) error {
	p.mu.Lock()
	if !force && p.prep {
		p.mu.Unlock()
		return nil
	}
	p.mu.Unlock()

	if p.t.hasHeader {
		offset += headerSize
	}
	if _, err := p.t.src.Seek(offset, 0); err != nil {
		return err
	}
	var bufs []al.Buffer
	// TODO(jbd): Limit the number of buffers in use, unqueue and reuse
	// the existing buffers as buffers are processed.
	buf := make([]byte, 128*1024)
	size := offset
	for {
		n, err := p.t.src.Read(buf)
		if n > 0 {
			size += int64(n)
			b := al.GenBuffers(1)
			b[0].BufferData(formatCodes[p.t.format], buf[:n], int32(p.t.samplesPerSecond))
			bufs = append(bufs, b[0])
		}
		if err == io.EOF {
			break
		}
		if err != nil {
			return err
		}
	}

	p.mu.Lock()
	if len(p.bufs) > 0 {
		p.source.UnqueueBuffers(p.bufs...)
		al.DeleteBuffers(p.bufs...)
	}
	p.sizeBytes = size
	p.bufs = bufs
	p.prep = true
	if len(bufs) > 0 {
		p.source.QueueBuffers(bufs...)
	}
	p.mu.Unlock()
	return nil
}
Ejemplo n.º 6
0
// NewPianoKey returns a key for our piano.
func NewPianoKey(pos mgl32.Vec3, lightColor mgl32.Vec3, white bool, freq float32) PianoKey {
	var color mgl32.Vec4
	var keySize float32
	if white {
		color = mgl32.Vec4{0.98, 0.97, 0.94}
		keySize = 2
	} else {
		color = mgl32.Vec4{0.1, 0.1, 0.1, 1.0}
		keySize = 1

	}
	pk := PianoKey{Pos: pos, Angle: 0, Color: color, Frequency: freq, Finger: -1, white: white, LightColor: lightColor}
	pk.BBox[0] = pos.Sub(mgl32.Vec3{0.5, 0.6, keySize})
	pk.BBox[1] = pos.Add(mgl32.Vec3{0.5, 0.6, keySize})
	pk.source = al.GenSources(1)[0]
	pk.source.SetGain(1.0)
	pk.source.SetPosition(al.Vector{pos.X(), pos.Y(), pos.Z()})
	pk.source.SetVelocity(al.Vector{})
	pk.buffers = al.GenBuffers(3)

	var samples [1024 * 16]int16

	sampleRate := 44100
	amplitude := float32(0.8 * 0x7FFF)

	for i := 0; i < len(samples); i++ {
		val := f32.Sin((2.0 * math.Pi * freq) / float32(sampleRate) * float32(i))
		samples[i] = int16(amplitude * val)
	}

	buf := &bytes.Buffer{}
	binary.Write(buf, binary.LittleEndian, &samples)
	pk.buffers[0].BufferData(al.FormatMono16, buf.Bytes(), 44100)

	f, _ := os.Create("audio.raw")
	binary.Write(f, binary.LittleEndian, &samples)
	f.Close()

	return pk
}
Ejemplo n.º 7
0
// Get returns a slice of buffers of length b.size ready to receive data and be queued.
// If b.src reports processing at-least as many buffers as b.size, buffers up to b.size
// will be unqueued for reuse. Otherwise, new buffers will be generated.
//
// If the length of b.bufs has grown to be greater than maxbufs, a nil slice is returned.
func (b *Buffer) Get() (bufs []al.Buffer) {
	if proc := int(b.src.BuffersProcessed()); proc >= b.size {
		// advance by size, BuffersProcessed will report that many less next time.
		bufs = b.bufs[b.idx : b.idx+b.size]
		b.src.UnqueueBuffers(bufs)
		if code := al.Error(); code != 0 {
			log.Printf("snd/al: unqueue buffers failed [err=%v]\n", code)
		}
		b.idx = (b.idx + b.size) % len(b.bufs)
	} else if len(b.bufs) >= maxbufs {
		// likely programmer error, something has gone horribly wrong.
		log.Printf("snd/al: get buffers failed, maxbufs reached [len=%v]\n", len(b.bufs))
		return nil
	} else {
		// make more buffers to fill data regardless of what openal says about processed.
		bufs = al.GenBuffers(b.size)
		if code := al.Error(); code != 0 {
			log.Printf("snd/al: generate buffers failed [err=%v]\n", code)
		}
		b.bufs = append(b.bufs, bufs...)
	}
	return bufs
}
Ejemplo n.º 8
0
func (p *Player) prepare(background bool, offset int64, force bool) error {
	p.mu.Lock()
	if !force && p.prep {
		p.mu.Unlock()
		return nil
	}
	p.mu.Unlock()

	if p.t.hasHeader {
		offset += headerSize
	}
	if _, err := p.t.src.Seek(offset, 0); err != nil {
		return err
	}
	var bufs []al.Buffer
	// TODO(jbd): Limit the number of buffers in use, unqueue and reuse
	// the existing buffers as buffers are processed.
	buf := make([]byte, 128*1024)
	size := offset
	for {
		n, err := p.t.src.Read(buf)
		if n > 0 {
			size += int64(n)
			b := al.GenBuffers(1)
			if !background && p.t.format == Stereo16 {
				inputBuffer := bytes.NewBuffer(buf)
				outputBuffer := new(bytes.Buffer)
				var left, right int16

				// TODO: this might not be the best way to convert Stereo16 to Mono16, but it's something
				for converted := 0; converted < n; converted += 4 {
					binary.Read(inputBuffer, binary.LittleEndian, &left)
					binary.Read(inputBuffer, binary.LittleEndian, &right)

					binary.Write(outputBuffer, binary.LittleEndian, int16((int32(left)+int32(right))/2))
				}
				b[0].BufferData(formatCodes[Mono16], outputBuffer.Bytes(), int32(p.t.samplesPerSecond/2))

			} else {
				b[0].BufferData(formatCodes[p.t.format], buf[:n], int32(p.t.samplesPerSecond))
			}
			bufs = append(bufs, b[0])
		}
		if err == io.EOF {
			break
		}
		if err != nil {
			return err
		}
	}

	p.mu.Lock()
	if len(p.bufs) > 0 {
		p.source.UnqueueBuffers(p.bufs...)
		al.DeleteBuffers(p.bufs...)
	}
	p.sizeBytes = size
	p.bufs = bufs
	p.prep = true
	if len(bufs) > 0 {
		p.source.QueueBuffers(bufs...)
	}
	p.mu.Unlock()
	return nil
}