Go-based FM stereo transmitter with RDS, Windows-first and cross-platform
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

51 wiersze
1.5KB

  1. package aoiprxkit
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. )
  6. // DecodeL24BE decodes signed 24-bit big-endian PCM into int32 samples sign-extended to 32 bits.
  7. func DecodeL24BE(payload []byte, channels int) ([]int32, error) {
  8. if channels < 1 {
  9. return nil, fmt.Errorf("invalid channels: %d", channels)
  10. }
  11. if len(payload)%3 != 0 {
  12. return nil, fmt.Errorf("payload length %d is not divisible by 3", len(payload))
  13. }
  14. totalSamples := len(payload) / 3
  15. if totalSamples%channels != 0 {
  16. return nil, fmt.Errorf("payload sample count %d is not divisible by channels %d", totalSamples, channels)
  17. }
  18. out := make([]int32, totalSamples)
  19. j := 0
  20. for i := 0; i < len(payload); i += 3 {
  21. v := int32(payload[i])<<16 | int32(payload[i+1])<<8 | int32(payload[i+2])
  22. if v&0x800000 != 0 {
  23. v |= ^int32(0xFFFFFF)
  24. }
  25. out[j] = v
  26. j++
  27. }
  28. return out, nil
  29. }
  30. // DecodeS32LE decodes signed 32-bit little-endian PCM into int32 samples.
  31. func DecodeS32LE(payload []byte, channels int) ([]int32, error) {
  32. if channels < 1 {
  33. return nil, fmt.Errorf("invalid channels: %d", channels)
  34. }
  35. if len(payload)%4 != 0 {
  36. return nil, fmt.Errorf("payload length %d is not divisible by 4", len(payload))
  37. }
  38. totalSamples := len(payload) / 4
  39. if totalSamples%channels != 0 {
  40. return nil, fmt.Errorf("payload sample count %d is not divisible by channels %d", totalSamples, channels)
  41. }
  42. out := make([]int32, totalSamples)
  43. for i := 0; i < totalSamples; i++ {
  44. out[i] = int32(binary.LittleEndian.Uint32(payload[i*4 : i*4+4]))
  45. }
  46. return out, nil
  47. }