Tulanir

EAS header .wav audio generator

Mar 1st, 2021 (edited)
450
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # (Amplitude bug has been fixed)
  2. # (Severe LSB bug has been fixed...)
  3. # This program generates a classic digital EAS (SAME) header, with preamble followed by message data
  4. # According to standard, the header is repeated 3 times, including preamble, with 1 second inbetween.
  5. # It then saves the signal to an uncompressed .wav file with the given file name
  6. # The bits are encoded as 4 sine wave cycles for a 1 and 3 cycles for a 0, over a standard timespan of 1.92ms
  7. # Each character (ASCII standard) is transmitted least significant bit first
  8. # This program allows you to generate any header you want, but for valid headers, the format can be found at:
  9. # https://en.wikipedia.org/wiki/Specific_Area_Message_Encoding
  10.  
  11. from math import sin, pi
  12. import wave
  13.  
  14. # Freely modifiable variables:
  15. message = "Example message, type anything you want! (as long as it's ASCII)"
  16. filename = 'signalaudio.wav'
  17. rate = 44100 # sample rate in hz
  18. bitlength = 0.00192 # bit length in seconds, recommend not changing
  19. amplitude = 1.0 # range between 0 and 1
  20. # ----------
  21.  
  22. sample_width = 1
  23. max_amplitude = 2 ** (8 * sample_width) - 1
  24. half_max_amp = 0.5 * max_amplitude
  25. wav = wave.open(filename, 'wb')
  26. wav.setnchannels(1)
  27. wav.setsampwidth(sample_width)
  28. wav.setframerate(rate)
  29.  
  30. def bits_lsb(_bytes):
  31.     for byte in _bytes:
  32.         for i in range(8):
  33.             yield (byte >> i) & 1
  34.  
  35. def generate_bit_signal(ncycles):
  36.     cycle = bytearray()
  37.     samples_per_cycle = round(rate * bitlength / ncycles)
  38.     for i in range(samples_per_cycle):
  39.         cycle.append(round(amplitude * half_max_amp * sin(i * 2 * pi / samples_per_cycle) + half_max_amp))
  40.     return bytes(cycle * ncycles)
  41.  
  42. MARK = generate_bit_signal(4)
  43. SPACE = generate_bit_signal(3)
  44.  
  45. def generate_byte_signal(_bytes):
  46.     signal = bytearray()
  47.     for bit in bits_lsb(_bytes):
  48.         signal.extend(MARK if bit == 1 else SPACE)
  49.     return bytes(signal)
  50.  
  51. data = (generate_byte_signal(b'\xAB' * 16 + bytes(message, encoding='ascii')) + bytes([int(half_max_amp)]) * rate) * 3
  52.  
  53. wav.writeframes(data)
  54. wav.close()
  55.  
RAW Paste Data