Wideband autonomous SDR analysis engine forked from sdr-visual-suite
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

86 satır
1.9KB

  1. package recorder
  2. import (
  3. "encoding/binary"
  4. "io"
  5. "os"
  6. )
  7. func writeWAV(path string, samples []float32, sampleRate int, channels int) error {
  8. f, err := os.Create(path)
  9. if err != nil {
  10. return err
  11. }
  12. defer f.Close()
  13. return writeWAVTo(f, samples, sampleRate, channels)
  14. }
  15. func writeWAVTo(w io.Writer, samples []float32, sampleRate int, channels int) error {
  16. if channels <= 0 {
  17. channels = 1
  18. }
  19. // 16-bit PCM
  20. dataSize := uint32(len(samples) * 2)
  21. // RIFF header
  22. if _, err := w.Write([]byte("RIFF")); err != nil {
  23. return err
  24. }
  25. if err := binary.Write(w, binary.LittleEndian, uint32(36)+dataSize); err != nil {
  26. return err
  27. }
  28. if _, err := w.Write([]byte("WAVE")); err != nil {
  29. return err
  30. }
  31. // fmt chunk
  32. if _, err := w.Write([]byte("fmt ")); err != nil {
  33. return err
  34. }
  35. if err := binary.Write(w, binary.LittleEndian, uint32(16)); err != nil {
  36. return err
  37. }
  38. if err := binary.Write(w, binary.LittleEndian, uint16(1)); err != nil { // PCM
  39. return err
  40. }
  41. if err := binary.Write(w, binary.LittleEndian, uint16(channels)); err != nil {
  42. return err
  43. }
  44. if err := binary.Write(w, binary.LittleEndian, uint32(sampleRate)); err != nil {
  45. return err
  46. }
  47. byteRate := uint32(sampleRate * channels * 2)
  48. if err := binary.Write(w, binary.LittleEndian, byteRate); err != nil {
  49. return err
  50. }
  51. if err := binary.Write(w, binary.LittleEndian, uint16(channels*2)); err != nil {
  52. return err
  53. }
  54. if err := binary.Write(w, binary.LittleEndian, uint16(16)); err != nil { // bits
  55. return err
  56. }
  57. // data chunk
  58. if _, err := w.Write([]byte("data")); err != nil {
  59. return err
  60. }
  61. if err := binary.Write(w, binary.LittleEndian, dataSize); err != nil {
  62. return err
  63. }
  64. // samples
  65. for _, s := range samples {
  66. v := int16(clip(s * 32767))
  67. if err := binary.Write(w, binary.LittleEndian, v); err != nil {
  68. return err
  69. }
  70. }
  71. return nil
  72. }
  73. func clip(v float32) float32 {
  74. if v > 32767 {
  75. return 32767
  76. }
  77. if v < -32768 {
  78. return -32768
  79. }
  80. return v
  81. }