From af566e3bfea1cfc758a8490560b7fbdb43cbb52d Mon Sep 17 00:00:00 2001
From: MarStr <marcus@marstr.online>
Date: Fri, 5 Jul 2024 15:46:19 +0200
Subject: [PATCH] Initial commit of script to git repo

---
 Pilot2AWS.py | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 126 insertions(+)
 create mode 100644 Pilot2AWS.py

diff --git a/Pilot2AWS.py b/Pilot2AWS.py
new file mode 100644
index 0000000..87cfd92
--- /dev/null
+++ b/Pilot2AWS.py
@@ -0,0 +1,126 @@
+
+import boto3        # pip install boto3
+import pygame       # pip install pygame
+import time
+import io
+import random
+import os
+
+# -------------------------------------------------------------------
+# Enter your access data and your AWS region
+# -------------------------------------------------------------------
+atc_aws_key    = "YOUR_AWS_KEY"
+atc_aws_secret = "YOUR_AWS_SECRET"
+atc_aws_region = "YOUR_REGION"
+# -------------------------------------------------------------------
+
+# -------------------------------------------------------------------
+# Do you want to see ATC messages in the console also?
+# -------------------------------------------------------------------
+atc_show_responses = True
+
+# -------------------------------------------------------------------
+# The voice model you want to use.
+#
+# IMPORTANT:
+# Depending on the model you want, the prices are per 1m characters
+# generated vary *drastically*.
+# 'standard' is the cheapest, 'neural' the most expensive one.
+# Depending on the model you pick, the list of voices vary also.
+#
+# Pricing: https://aws.amazon.com/polly/pricing/
+# -------------------------------------------------------------------
+atc_aws_voicemodel = 'standard'
+# atc_aws_voicemodel = 'neural'
+
+
+# -------------------------------------------------------------------
+# Define where your Pilot2ATC conversation file is located
+# This file can be anywhere and have any name - just make sure you
+# put in the correct absolute path into this variable.
+# -------------------------------------------------------------------
+atc_pilot2atc_log = "C:\\Users\\Marcus\\Desktop\\ConversationText.txt"
+
+
+# -------------------------------------------------------------------
+# NO TRESPASSING BEYOND THIS POINT
+# -------------------------------------------------------------------
+
+os.system("cls")
+print("  ")
+print(" ---------------------------------------------- ")
+print(" Pilot2AWS")
+print(" Making Pilot2ATC sound more natural")
+print(" ---------------------------------------------- ")
+print(" Developed by MarStrMind")
+print(" License: MIT")
+print(" ---------------------------------------------- ")
+print(" Using file: " + atc_pilot2atc_log)
+print(" ---------------------------------------------- ")
+print("  ")
+
+# The voice names available for playback, depending on the model
+# Of course, you can remove any that you do not like
+# Sources for voice names:
+# - https://docs.aws.amazon.com/polly/latest/dg/neural-voices.html
+# - https://docs.aws.amazon.com/polly/latest/dg/standard-voices.html
+atc_voices = None
+if atc_aws_voicemodel == "standard":
+    atc_voices = ["Nicole", "Russell", "Amy", "Emma", "Brian", "Aditi", "Raveena", "Joanna", "Kendra", "Kimberly", "Salli", "Joey", "Geraint"]
+    # After testing, I removed Ivy from this list. It sounded too child-like.
+if atc_aws_voicemodel == "neural":
+    atc_voices = ["Olivia", "Amy", "Emma", "Brian", "Arthur", "Kajal", "Niamh", "Aria", "Ayanda", "Danielle", "Gregory", "Ivy", "Joanna", "Kendra", "Kimberly", "Salli", "Joey", "Matthew", "Ruth", "Stephen"]
+    # Missing in this list are Justin and Kevin -
+    # they are declared as being young child voices - you normally do not hear children on an ATC transmission.
+
+
+# Setup our Polly session to AWS
+atc_polly_client = boto3.Session(
+                aws_access_key_id=atc_aws_key,                     
+                aws_secret_access_key=atc_aws_secret,
+                region_name=atc_aws_region).client('polly')
+
+# Last read line
+atc_last_line = -1
+
+# Init pygame and its mixer
+pygame.init()
+pygame.mixer.init()
+
+# Open file before main loop
+atc_log = open(atc_pilot2atc_log)
+
+# Main run loop
+while True:
+    atc_lines = atc_log.readlines()
+    idx = 0
+    for line in atc_lines:
+        if "      ATC: " in line:
+            line = line.replace("      ATC: ", "")
+            if idx > atc_last_line:
+                # Update last read line
+                atc_last_line = idx
+
+                # Pick a voice
+                voice_to_use = random.randrange(len(atc_voices))
+
+                # Show what has been said so that it can be verified outside of Pilot2ATC - if the user wants it
+                if atc_show_responses == True:
+                    print(" > ATC - [" + atc_voices[voice_to_use] + "]: " + line)
+
+                # Generate voice!
+                # Let's keep it at OGG - best compromize between data transfer size and quality
+                response = atc_polly_client.synthesize_speech(VoiceId=atc_voices[voice_to_use], OutputFormat='ogg_vorbis', Text = line, Engine = atc_aws_voicemodel)
+                # And place that into a binary block
+                data = io.BytesIO(response['AudioStream'].read())
+
+                # Place the data into pygame and play it
+                pygame.mixer.music.load(data)
+                pygame.mixer.music.play()
+                pygame.event.wait()
+        
+        # Increase loop count
+        idx = idx + 1
+
+    atc_log.seek(0)
+    time.sleep(3)