Пример #1
0
// drawFrequonsFourier draws the frequency-domain representation of Frequons.
func drawFrequonsFourier(pm nimble.PixMap) {
	c := universe.Zoo
	h := harmonicStorage[:len(c)]

	var ampScale float32
	if autoGain.Value {
		// Compute L1 norm of amplitudes
		norm := float32(0)
		for i := range c {
			norm += math32.Abs(c[i].Amplitude)
		}
		ampScale = 1 / norm
	} else {
		ampScale = 1 / float32(len(c))
	}
	fracX, fracY := universe.BoxFraction()
	fracX *= zoomCompression
	fracY *= zoomCompression
	sizeX, sizeY := pm.Size()

	// Set up harmonics
	// (cx,cy) is center of fourier view
	cx, cy := 0.5*float32(sizeX)*fracX, 0.5*float32(sizeY)*fracY
	α, β := -0.5*cx, -0.5*cy
	ωScale := 200. / float32(sizeX*sizeY)
	for i := range h {
		ωx := (c[i].Sx - cx) * ωScale
		ωy := (c[i].Sy - cy) * ωScale
		h[i].Ωx = ωx
		h[i].Ωy = ωy
		h[i].Phase = α*ωx + β*ωy + phaseRoll
		// Scale amplitude so that DFT values fit within domain of color lookup table.
		h[i].Amplitude = c[i].Amplitude * ampScale
	}

	marginX := int32(math32.Round(0.5 * float32(sizeX) * (1 - fracX)))
	marginY := int32(math32.Round(0.5 * float32(sizeY) * (1 - fracY)))
	fourier.Draw(pm.Intersect(nimble.Rect{
		Left:   marginX,
		Right:  sizeX - marginX,
		Top:    marginY,
		Bottom: sizeY - marginY,
	}), h, universe.Scheme())
	if marginX != 0 || marginY != 0 {
		pm.DrawRect(nimble.Rect{Left: 0, Right: sizeX, Top: 0, Bottom: marginY}, nimble.Black)
		pm.DrawRect(nimble.Rect{Left: 0, Right: sizeX, Top: sizeY - marginY, Bottom: sizeY}, nimble.Black)
		pm.DrawRect(nimble.Rect{Left: 0, Right: marginX, Top: marginY, Bottom: sizeY - marginY}, nimble.Black)
		pm.DrawRect(nimble.Rect{Left: sizeX - marginX, Right: sizeX, Top: marginY, Bottom: sizeY - marginY}, nimble.Black)
	}
}
Пример #2
0
func init() {
	Twang = makeSound(44100, func(i float32) float32 {
		const ω = 110 * 2 * π / nimble.SampleRate
		const nharmonic = 32
		sum := float32(0)
		for h := float32(1); h <= nharmonic; h++ {
			sum += math32.Sin(ω*h*i) * math32.Exp(-i*0.00004*h)
		}
		return sum / nharmonic
	})

	n := len(Twang)
	AntiTwang = make([]float32, n)
	for i := range AntiTwang {
		AntiTwang[i] = Twang[n-1-i]
	}

	sum := float32(0)
	Broken = makeSound(44100, func(i float32) float32 {
		r := (rand.Float32() - 0.5) * (1.0 / 16)
		newSum := sum + r
		if math32.Abs(newSum) < 1.0 {
			sum = newSum
		}
		sum *= (1 - 1/32.0)
		return sum * math32.Exp(-i*.0001)
	})

	Wobble = makeSound(44100, func(i float32) float32 {
		return 0.25 * math32.Sin((440+44*math32.Sin(i*0.001))*i*(2*π/nimble.SampleRate)) * math32.Exp(-i*0.00005)
	})

	partials := [...]float32{0.56, 0.92, 1.19, 1.71, 2.00, 2.74, 3.00, 3.76, 4.07}
	Bell = makeSound(44100, func(i float32) float32 {
		const θ = 512 * 2 * π / nimble.SampleRate
		sum := float32(0)
		const n = float32(len(partials))
		for j := range partials {
			sum += math32.Sin(i * θ * partials[j])
		}
		return sum * (1.0 / n) * math32.Exp(-i*0.0001)
	})
}