1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
#!/usr/bin/env python
import sys, wave
#
# "Modem" wav creator for "Next Gen" Tagsu Modem :)
#
# Author: Jari Tulilahti
# Copyright: 2014 Rakettitiede Oy
# License: LGPLv3, see COPYING and COPYING.LESSER -files for more info
#
# Usage:
# python modem.py <input_filename> [output_wav_filename] [samplerate]
#
# Default sample rate is 48000
# Default output to stdout if no wav filename given
#
# Working sample rates are between 16000 - 48000:
#
# 16000 (~4000 bps)
# 22050 (~5500 bps)
# 24000 (~6000 bps)
# 32000 (~8000 bps)
# 44100 (~11025 bps)
# 48000 (~12000 bps)
#
# NOTICE:
#
# Actual speed depends of the data, as zeroes and ones take
# different amount of samples, the more zeros, the faster the speed.
# Average bps has been calculated using data "0101010101..."
#
class modem:
bits = [[3 * chr(0), 5 * chr(0)], [3 * chr(255), 5 * chr(255)]]
sync = [17 * chr(0), 17 * chr(255)]
hilo = 0
# Nothing here
def __init__(self):
pass
# Generate one sync-pulse
def syncsignal(self):
self.hilo ^= 1
return self.sync[self.hilo]
# Decode bits to modem signals
def modemcode(self, byte):
bleep = ""
for x in xrange(8):
self.hilo ^= 1
bleep += self.bits[self.hilo][byte & 0x01]
byte >>= 1
return bleep
# Return <length> samples of silence
def silence(self, length):
return chr(127) * length
if len(sys.argv) < 2:
print """Usage: {0} <input_filename> [output_wav_filename] [samplerate]
input_filename Data file as input to modem.
output_wav_filename Write output-wav to this file. If empty, output to STDOUT.
samplerate Sample rate between 16000 - 48000. Default is 48000.
""".format(sys.argv[0])
sys.exit()
sound = ""
m = modem()
cnt = 0
# Add silence
# sound += m.silence(24000)
# Add 4 sync signals to start
for x in xrange(4):
sound += m.syncsignal()
# Send Actual data
f = open(sys.argv[1])
for byte in f.read():
sound += m.modemcode(ord(byte))
# Add counter
cnt += 1
# After every 10 bytes, send 2 sync signals
if cnt == 10:
for x in xrange(2):
sound += m.syncsignal()
cnt = 0
# End transmission with few sync-signals
for x in xrange(4):
sound += m.syncsignal()
# Output the generated sound (no wav headers)
if len(sys.argv) <= 2:
print sound
else:
freq = int(sys.argv[3]) if len(sys.argv) > 3 else 48000
wav = wave.open(sys.argv[2], 'wb')
wav.setparams((1, 1, freq, 0, "NONE", None))
wav.writeframes(sound)
wav.close()
|