// Start the player by initializing state and playing the tone func (player *Player) Start(sound s.Sound) { fmt.Printf("Player starting...\n") player.running = true player.started = true go func() { output.Play(sound) }() }
// Generates the golden files. See test/sounds_test.go for actual test. func main() { // Singlethreaded for now... runtime.GOMAXPROCS(4) // Parse flags... sampleRate := s.CyclesPerSecond minFreq := flag.Float64("minFreq", 110.0, "minimum frequency") maxFreq := flag.Float64("maxFreq", 14080.0, "maximum frequency") bpo := flag.Int("bpo", 24, "Buckets per octave") flag.Parse() remainingArgs := flag.Args() if len(remainingArgs) < 1 || len(remainingArgs) > 2 { panic("Required: <input> [<input>] filename arguments") } inputFile := remainingArgs[0] inputFile2 := inputFile if len(remainingArgs) == 2 { inputFile2 = remainingArgs[1] } inputSound := f.Read(inputFile) // inputSound := s.NewTimedSound(s.NewSineWave(440.0), 1000) inputSound.Start() defer inputSound.Stop() // minFreq, maxFreq, bpo := 110.0, 14080.0, 24 params := cq.NewCQParams(sampleRate, *minFreq, *maxFreq, *bpo) constantQ := cq.NewConstantQ(params) cqInverse := cq.NewCQInverse(params) latency := constantQ.OutputLatency + cqInverse.OutputLatency // Two inputs version - TODO, switch back to input + output. inputSound2 := f.Read(inputFile2) inputSound2.Start() defer inputSound2.Stop() constantQ2 := cq.NewConstantQ(params) startTime := time.Now() // TODO: Skip the first 'latency' samples for the stream. fmt.Printf("TODO: Skip latency (= %d) samples)\n", latency) columns := constantQ.ProcessChannel(inputSound.GetSamples()) columns2 := constantQ2.ProcessChannel(inputSound2.GetSamples()) samples := cqInverse.ProcessChannel(mergeChannels(columns, columns2)) asSound := s.WrapChannelAsSound(samples) // if outputFile != "" { // f.Write(asSound, outputFile) // } else { output.Play(asSound) // } elapsedSeconds := time.Since(startTime).Seconds() fmt.Printf("elapsed time (not counting init): %f sec\n", elapsedSeconds) }
// Generates the golden files. See test/sounds_test.go for actual test. func main() { // Needs to be at least 2 when doing openGL + sound output at the same time. runtime.GOMAXPROCS(3) sampleRate := s.CyclesPerSecond minFreq := flag.Float64("minFreq", 27.5*4.0, "minimum frequency") maxFreq := flag.Float64("maxFreq", 3520.0/4.0, "maximum frequency") octaves := 3 bpo := flag.Int("bpo", 72, "Buckets per octave") flag.Parse() remainingArgs := flag.Args() argCount := len(remainingArgs) if argCount < 1 || argCount > 2 { panic("Required: <input> [<output>] filename arguments") } inputFile := remainingArgs[0] outputFile := "" if argCount == 2 { outputFile = remainingArgs[1] } // minFreq, maxFreq, bpo := 110.0, 14080.0, 24 params := cq.NewCQParams(sampleRate, *minFreq, *maxFreq, *bpo) spectrogram := cq.NewSpectrogram(params) inputSound := f.Read(inputFile) // fmt.Printf("TODO: Go back to reading %s\n", inputFile) // inputSound := s.NewTimedSound( // s.SumSounds( // s.NewSineWave(440.00), // // s.NewSineWave(440.00), // s.NewSineWave(698.46), // ), 10000) inputSound.Start() defer inputSound.Stop() startTime := time.Now() if outputFile != "" { // Write to file columns := spectrogram.ProcessChannel(inputSound.GetSamples()) outputBuffer := bytes.NewBuffer(make([]byte, 0, 1024)) width, height := 0, 0 for col := range columns { for _, c := range col { cq.WriteComplex(outputBuffer, c) } if width%1000 == 0 { fmt.Printf("At frame: %d\n", width) } width++ height = len(col) } fmt.Printf("Done! - %d by %d\n", width, height) ioutil.WriteFile(outputFile, outputBuffer.Bytes(), 0644) } else { // No file, so play and show instead: soundChannel, specChannel := splitChannel(inputSound.GetSamples()) go func() { columns := spectrogram.ProcessChannel(specChannel) toShow := util.NewSpectrogramScreen(882, *bpo*octaves, *bpo) toShow.Render(columns, 1) }() output.Play(s.WrapChannelAsSound(soundChannel)) } elapsedSeconds := time.Since(startTime).Seconds() fmt.Printf("elapsed time (not counting init): %f sec\n", elapsedSeconds) if outputFile == "" { // Hang around to the view can be looked at. for { } } }
// playClairDeLune builds then plays Clair de Lune (Debussey) // music from http://www.piano-midi.de/noten/debussy/deb_clai.pdf func playClairDeLune() { fmt.Println("Building sound.") /* finalNoteLength := float64(3 + 6) // 6 extra beats, just for effect // Left-hand split for a bit near the end. rh1 := s.ConcatSounds( notesT(7, fs(1)), notesTQRun(0, 1, 0, 3, 0, -1, 0), notesT(2, fs(-1)), notesTQRun(-2, -1), notesT(3, fs(-2)), notesT(finalNoteLength, fs(-3)), ) rh2 := s.ConcatSounds( notesT(6, fs(-1)), notesT(6, fs(-2)), notesT(3, fs(-2)), notesT(6, fs(-4)), notesT(finalNoteLength, fs(-4)), ) // Split of couplets over long Bb couplets := s.SumSounds( s.ConcatSounds(notesT(1.5, fs(2)), notesT(3, fs(4)), notesT(2.5, fs(2))), notesT(7, fs(0)), ) // Top half of the score: rightHand := s.ConcatSounds( rest(2), notesT(4, fs(4, 6)), notesT(4, fs(2, 4)), notesT(1, fs(1, 3)), notesT(1, fs(2, 4)), notesT(7, fs(1, 3)), notesT(1, fs(0, 2)), notesT(1, fs(1, 3)), couplets, notesT(1, fs(-1, 1)), notesT(1, fs(0, 2)), s.SumSounds(rh1, rh2), ) // Bottom half. leftHand := s.ConcatSounds( rest(1), notesT(8, fs(-1, -3)), notesT(9, fs(-0.5, -2)), notesT(9, fs(-1, -3)), notesT(9, fs(-2, -4)), notesT(6, fs(-4, -5)), notesT(3, fs(-4, -6)), notesT(6, fs(-5, -7)), // HACK: Actually in bass clef, but rewritten in treble for these two chords. notesT(finalNoteLength, fs(-6, -7.5)), ) clairDeLune := s.SumSounds(leftHand, rightHand) */ // toPlay := s.NewDenseIIR(clairDeLune, // []float64{0.8922, -2.677, 2.677, -0.8922}, // []float64{2.772, -2.57, 0.7961}, // ) // hz := 440.0 // toPlay := s.SumSounds( // s.NewSineWave(hz), // s.NewSquareWave(hz), // s.NewSawtoothWave(hz), // s.NewTriangleWave(hz), // ) toPlay := s.NewJackInput("go-sound-in") // toPlay := s.NewTimedSound(s.NewSineWave(500), 1000) // toPlay := s.SumSounds(s1, s2) // toPlay := s.NewTimedSound(shephardTones(), 10000) // toPlay := file.Read("greatgig.flac") // file.Write(toPlay, "gg.wav") // fmt.Printf("Playing: \n\t%s\n", toPlay) // output.Render(toPlay, 2000, 400) // output.PlayJack(toPlay) output.Play(toPlay) // output.Play(s.LoadFlacAsSound("toneslide.flac")) // Optional: Write to a .wav file: // clairDeLune.Reset() // fmt.Println("Writing sound to file.") // file.Write(clairDeLune, "clairdelune.wav") // Optional: Draw to screen: // clairDeLune.Reset() // fmt.Println("Drawing sound to screen.") // output.Render(clairDeLune, 2000, 400) }