summaryrefslogtreecommitdiff
path: root/utilities/modem.py
blob: f2e2b1bbd0cb9f24cb440e7860289fc739a62bdf (plain)
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()