wavegen.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. package mz700_tape_wav_gen
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. "github.com/zenwerk/go-wave"
  6. "io"
  7. "math"
  8. )
  9. type MZ700TapeWavGen struct {
  10. wwr *wave.Writer
  11. longPulseData []int16
  12. shortPulseData []int16
  13. shortGapData []int16
  14. longGapData []int16
  15. silent1s []int16
  16. lastError error
  17. mc machineRelatedConfig
  18. hlv int16
  19. llv int16
  20. }
  21. func (g *MZ700TapeWavGen) Write(p []byte) (n int, err error) {
  22. l := len(p)
  23. for _, b := range p {
  24. g.WriteDataByte(b)
  25. }
  26. if g.lastError != nil {
  27. return 0, g.lastError
  28. }
  29. return l, nil
  30. }
  31. func NewMZ700TapeWavGen(f io.WriteCloser, machineType MachineType, invertPolarity bool) (*MZ700TapeWavGen, error) {
  32. g := &MZ700TapeWavGen{
  33. lastError: nil,
  34. mc: getMachineRelatedConfigByType(machineType),
  35. }
  36. if g.mc.Unsupported {
  37. return nil, fmt.Errorf("unsupported machine type")
  38. }
  39. if invertPolarity {
  40. g.llv = math.MaxInt16 / 2
  41. g.hlv = math.MinInt16 / 2
  42. } else {
  43. g.llv = math.MinInt16 / 2
  44. g.hlv = math.MaxInt16 / 2
  45. }
  46. wwrp := wave.WriterParam{
  47. Out: f,
  48. Channel: 1,
  49. SampleRate: 44100,
  50. BitsPerSample: 16,
  51. }
  52. var err error
  53. g.wwr, err = wave.NewWriter(wwrp)
  54. if err != nil {
  55. return nil, err
  56. }
  57. g.initPulseDataTemplate()
  58. return g, nil
  59. }
  60. func (g *MZ700TapeWavGen) initPulseDataTemplate() {
  61. g.longPulseData = make([]int16, g.mc.LongPulseSampleTotal)
  62. g.shortPulseData = make([]int16, g.mc.ShortPulseSampleTotal)
  63. for i := 0; i < g.mc.ShortPulseSampleHigh; i++ {
  64. g.shortPulseData[i] = g.hlv
  65. }
  66. for i := g.mc.ShortPulseSampleHigh; i < g.mc.ShortPulseSampleTotal; i++ {
  67. g.shortPulseData[i] = g.llv
  68. }
  69. for i := 0; i < g.mc.LongPulseSampleHigh; i++ {
  70. g.longPulseData[i] = g.hlv
  71. }
  72. for i := g.mc.LongPulseSampleHigh; i < g.mc.LongPulseSampleTotal; i++ {
  73. g.longPulseData[i] = g.llv
  74. }
  75. g.shortGapData = make([]int16, g.mc.ShortGapSize*g.mc.ShortPulseSampleTotal)
  76. g.longGapData = make([]int16, g.mc.LongGapSize*g.mc.ShortPulseSampleTotal)
  77. for j := 0; j < g.mc.ShortGapSize; j++ {
  78. for i := 0; i < g.mc.ShortPulseSampleHigh; i++ {
  79. g.shortGapData[j*g.mc.ShortPulseSampleTotal+i] = g.hlv
  80. }
  81. for i := g.mc.ShortPulseSampleHigh; i < g.mc.ShortPulseSampleTotal; i++ {
  82. g.shortGapData[j*g.mc.ShortPulseSampleTotal+i] = g.llv
  83. }
  84. }
  85. for j := 0; j < g.mc.LongGapSize; j++ {
  86. for i := 0; i < g.mc.ShortPulseSampleHigh; i++ {
  87. g.longGapData[j*g.mc.ShortPulseSampleTotal+i] = g.hlv
  88. }
  89. for i := g.mc.ShortPulseSampleHigh; i < g.mc.ShortPulseSampleTotal; i++ {
  90. g.longGapData[j*g.mc.ShortPulseSampleTotal+i] = g.llv
  91. }
  92. }
  93. g.silent1s = make([]int16, 44100)
  94. for i := 0; i < 44100; i++ {
  95. g.silent1s[i] = 0
  96. }
  97. }
  98. func (g *MZ700TapeWavGen) GetLastError() error {
  99. return g.lastError
  100. }
  101. func (g *MZ700TapeWavGen) WriteLongPulse() {
  102. _, err := g.wwr.WriteSample16(g.longPulseData)
  103. if err != nil {
  104. g.lastError = err
  105. }
  106. }
  107. func (g *MZ700TapeWavGen) WriteShortPulse() {
  108. _, err := g.wwr.WriteSample16(g.shortPulseData)
  109. if err != nil {
  110. g.lastError = err
  111. }
  112. }
  113. func (g *MZ700TapeWavGen) WriteBit(b bool) {
  114. if b {
  115. g.WriteLongPulse()
  116. } else {
  117. g.WriteShortPulse()
  118. }
  119. }
  120. func (g *MZ700TapeWavGen) WriteDataByte(b byte) {
  121. var mask uint8
  122. for mask = 0x80; mask >= 1; mask = mask >> 1 {
  123. if b&mask > 0 {
  124. g.WriteLongPulse()
  125. } else {
  126. g.WriteShortPulse()
  127. }
  128. }
  129. g.WriteLongPulse()
  130. }
  131. func (g *MZ700TapeWavGen) WriteGAP(isLong bool) {
  132. var err error
  133. if isLong {
  134. _, err = g.wwr.WriteSample16(g.longGapData)
  135. } else {
  136. _, err = g.wwr.WriteSample16(g.shortGapData)
  137. }
  138. if err != nil {
  139. g.lastError = err
  140. }
  141. }
  142. func (g *MZ700TapeWavGen) WriteTapeMark(isLong bool) {
  143. var tl int
  144. if isLong {
  145. tl = g.mc.LongTapemarkSize
  146. } else {
  147. tl = g.mc.ShortTapemarkSize
  148. }
  149. for i := 0; i < tl; i++ {
  150. g.WriteLongPulse()
  151. }
  152. for i := 0; i < tl; i++ {
  153. g.WriteShortPulse()
  154. }
  155. for i := 0; i < g.mc.TapemarkEndLongPulse; i++ {
  156. g.WriteLongPulse()
  157. }
  158. }
  159. func (g *MZ700TapeWavGen) Write256S() {
  160. for i := 0; i < 256; i++ {
  161. g.WriteShortPulse()
  162. }
  163. }
  164. func (g *MZ700TapeWavGen) WriteFileAttribute(attr byte) {
  165. g.WriteDataByte(attr)
  166. }
  167. // Return checksum
  168. func (g *MZ700TapeWavGen) WriteFilenameRaw(fnraw []byte) uint16 {
  169. chksum := GetByteSliceChecksum(fnraw)
  170. _, g.lastError = g.Write(fnraw)
  171. return chksum
  172. }
  173. // Return checksum. Sizes, addresses are in little endian.
  174. func (g *MZ700TapeWavGen) WriteUint16LittleEndian(n uint16) uint16 {
  175. b := make([]byte, 2)
  176. binary.LittleEndian.PutUint16(b, n)
  177. var chksum uint16 = 0
  178. chksum += GetSingleByteChecksum(b[0])
  179. chksum += GetSingleByteChecksum(b[1])
  180. _, g.lastError = g.Write(b)
  181. return chksum
  182. }
  183. // Return checksum. Checksums are in big endian.
  184. func (g *MZ700TapeWavGen) WriteUint16BigEndian(n uint16) uint16 {
  185. b := make([]byte, 2)
  186. binary.BigEndian.PutUint16(b, n)
  187. var chksum uint16 = 0
  188. chksum += GetSingleByteChecksum(b[0])
  189. chksum += GetSingleByteChecksum(b[1])
  190. _, g.lastError = g.Write(b)
  191. return chksum
  192. }
  193. // Return checksum
  194. func (g *MZ700TapeWavGen) WriteCommentRaw(rb []byte) uint16 {
  195. l := len(rb)
  196. if l > 104 {
  197. g.lastError = fmt.Errorf("comment too long")
  198. return 0
  199. }
  200. var wb []byte
  201. if l == 104 {
  202. wb = rb
  203. } else {
  204. wb = PaddingRawComment(rb)
  205. }
  206. chksum := GetByteSliceChecksum(wb)
  207. _, g.lastError = g.Write(wb)
  208. return chksum
  209. }
  210. func (g *MZ700TapeWavGen) WriteSilent1Second() {
  211. var err error
  212. _, err = g.wwr.WriteSample16(g.silent1s)
  213. if err != nil {
  214. g.lastError = err
  215. }
  216. }
  217. func (g *MZ700TapeWavGen) Close() error {
  218. err := g.wwr.Close()
  219. if err != nil {
  220. return err
  221. } else {
  222. return g.lastError
  223. }
  224. }