// 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]...) } }
func AddSource(in snd.Sound) error { switch in.Channels() { case 1: hwa.format = al.FormatMono16 case 2: hwa.format = al.FormatStereo16 default: return fmt.Errorf("snd/al: can't handle input with channels(%v)", in.Channels()) } hwa.in = in hwa.out = make([]byte, in.BufferLen()*2) s := al.GenSources(1) if code := al.Error(); code != 0 { return fmt.Errorf("snd/al: generate source failed [err=%v]", code) } hwa.source = s[0] hwa.buf.src = s[0] log.Println("snd/al: software latency", SoftLatency()) hwa.inputs = snd.GetInputs(in) return nil }
// NewPlayer returns a new Player. // It initializes the underlying audio devices and the related resources. // If zero values are provided for format and sample rate values, the player // determines them from the source's WAV header. // An error is returned if the format and sample rate can't be determined. func NewPlayer(src ReadSeekCloser, format Format, samplesPerSecond int64) (*Player, error) { if err := al.OpenDevice(); err != nil { return nil, err } if err := createContext(); err != nil { return nil, err } s := al.GenSources(1) if code := al.Error(); code != 0 { return nil, fmt.Errorf("audio: cannot generate an audio source [err=%x]", code) } p := &Player{ t: &track{format: format, src: src, samplesPerSecond: samplesPerSecond}, source: s[0], } if err := p.discoverHeader(); err != nil { return nil, err } if p.t.format == 0 { return nil, errors.New("audio: cannot determine the format") } if p.t.samplesPerSecond == 0 { return nil, errors.New("audio: cannot determine the sample rate") } return p, nil }
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 }
// 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 }
func NewContext(oscillator model.Oscillator) *Context { if err := al.OpenDevice(); err != nil { log.Fatal(err) } s := al.GenSources(1) if code := al.Error(); code != 0 { log.Fatalln("openal error:", code) } return &Context{ source: s[0], queue: []al.Buffer{}, oscillator: oscillator, } }
func NewContext(oscilator Oscilator) *Context { if err := al.OpenDevice(); err != nil { log.Fatal(err) } s := al.GenSources(1) if code := al.Error(); code != 0 { log.Fatalln("openal error:", code) } //s[0].SetGain(s[0].MaxGain()) //s[0].SetPosition(al.ListenerPosition()) return &Context{ source: s[0], queue: []al.Buffer{}, oscilator: oscilator, } }
// 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 }