Advertisement
AyPeeEye

HRIR Generator

Dec 5th, 2023 (edited)
709
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.57 KB | None | 0 0
  1. # 7.1 + stereo HeSuVi HRIR generator
  2. # Made by AyPeeEye in collaboration with ChatGPT
  3. # requires the library soundfile-0.12.1 and Python version 3.8 (may work with other versions but no guarantees)
  4. import tkinter as tk
  5. from tkinter import filedialog
  6. import soundfile as sf
  7.  
  8. # Function to create and write to a peace preset output file
  9. def generate_hrir_file(file_paths, output_filename):
  10.     num_channels = 0
  11.     for path in enumerate(file_paths):
  12.         if path[1] != "None":
  13.             num_channels += 1
  14.     if (num_channels != 1) and (num_channels != 2) and (num_channels != 7):
  15.         return 1    # Not a supported speaker configuration
  16.     if num_channels == 2 and (file_paths[1] == "None" or file_paths[2] == "None"):
  17.         return 2    # Wrong channel config for stereo
  18.     if num_channels == 1 and (file_paths[0] == "None"):
  19.         return 5    # Wrong channel config for HeSuVi to stereo
  20.    
  21.     # HeSuVi to stereo
  22.     if num_channels == 1:
  23.         channel_data, samplerate = sf.read(file_paths[0])
  24.         if len(channel_data[1]) != 14:
  25.             return 6    # Not a 14 channel HeSuVi file
  26.         fl_left = channel_data[:, 0]  # Extract left channel
  27.         fl_right = channel_data[:, 1]  # Extract right channel
  28.         fr_left = channel_data[:, 7]  # Extract left channel
  29.         fr_right = channel_data[:, 8]  # Extract right channel        
  30.        
  31.         # Create a 4-channel file by combining left and right channels
  32.         # Here we'll duplicate the left and right channels to create a 4-channel file
  33.         four_channel_data = [fl_left, fl_right, fr_left, fr_right]
  34.        
  35.         # Reshape the data into a 4-channel format
  36.         four_channel_data = list(map(list, zip(*four_channel_data)))  # Interleave the channels
  37.        
  38.         # Save the 4-channel audio data
  39.         sf.write(output_filename+'.wav', four_channel_data, samplerate, format='WAV', subtype='PCM_24')
  40.         return 0    # Generation finished without errors
  41.    
  42.     # Stereo HRIR generator
  43.     if num_channels == 2:
  44.         stereo_data_fl, samplerate_0 = sf.read(file_paths[1])
  45.         if stereo_data_fl.shape[1] != 2:
  46.             return 3    # File not stereo
  47.         stereo_data_fr, samplerate_1 = sf.read(file_paths[2])
  48.         if stereo_data_fr.shape[1] != 2:
  49.             return 3    # File not stereo
  50.         if samplerate_0 != samplerate_1:
  51.             return 4    # Not the same sample rate
  52.         fl_left = stereo_data_fl[:, 0]  # Extract left channel
  53.         fl_right = stereo_data_fl[:, 1]  # Extract right channel
  54.         fr_left = stereo_data_fr[:, 0]  # Extract left channel
  55.         fr_right = stereo_data_fr[:, 1]  # Extract right channel        
  56.        
  57.         # Create a 4-channel file by combining left and right channels
  58.         # Here we'll duplicate the left and right channels to create a 4-channel file
  59.         four_channel_data = [fl_left, fl_right, fr_left, fr_right]
  60.        
  61.         # Reshape the data into a 4-channel format
  62.         four_channel_data = list(map(list, zip(*four_channel_data)))  # Interleave the channels
  63.        
  64.         # Save the 4-channel audio data
  65.         sf.write(output_filename+'.wav', four_channel_data, samplerate_0, format='WAV', subtype='PCM_24')
  66.         return 0    # Generation finished without errors
  67.    
  68.     # 7.1 HRIR generator
  69.     if num_channels == 7:
  70.         stereo_data_fl, samplerate_0 = sf.read(file_paths[1])
  71.         if stereo_data_fl.shape[1] != 2:
  72.             return 3    # File not stereo
  73.         stereo_data_fr, samplerate_1 = sf.read(file_paths[2])
  74.         if stereo_data_fr.shape[1] != 2:
  75.             return 3    # File not stereo
  76.         stereo_data_fc, samplerate_2 = sf.read(file_paths[3])
  77.         if stereo_data_fc.shape[1] != 2:
  78.             return 3    # File not stereo
  79.         stereo_data_rl, samplerate_3 = sf.read(file_paths[4])
  80.         if stereo_data_rl.shape[1] != 2:
  81.             return 3    # File not stereo
  82.         stereo_data_rr, samplerate_4 = sf.read(file_paths[5])
  83.         if stereo_data_rr.shape[1] != 2:
  84.             return 3    # File not stereo
  85.         stereo_data_sl, samplerate_5 = sf.read(file_paths[6])
  86.         if stereo_data_sl.shape[1] != 2:
  87.             return 3    # File not stereo
  88.         stereo_data_sr, samplerate_6 = sf.read(file_paths[7])
  89.         if stereo_data_sr.shape[1] != 2:
  90.             return 3    # File not stereo
  91.         samplerates = [samplerate_0, samplerate_1, samplerate_2, samplerate_3, samplerate_4, samplerate_5, samplerate_6]
  92.         for i in range(1, len(samplerates)):
  93.             if samplerates[0] != samplerates[i]:
  94.                 return 4    # Not the same sample rate
  95.         fl_left = stereo_data_fl[:, 0]  # Extract left channel
  96.         fl_right = stereo_data_fl[:, 1]  # Extract right channel
  97.         fr_left = stereo_data_fr[:, 0]  # Extract left channel
  98.         fr_right = stereo_data_fr[:, 1]  # Extract right channel        
  99.         fc_left = stereo_data_fc[:, 0]  # Extract left channel
  100.         fc_right = stereo_data_fc[:, 1]  # Extract right channel
  101.         rl_left = stereo_data_rl[:, 0]  # Extract left channel
  102.         rl_right = stereo_data_rl[:, 1]  # Extract right channel    
  103.         rr_left = stereo_data_rr[:, 0]  # Extract left channel
  104.         rr_right = stereo_data_rr[:, 1]  # Extract right channel
  105.         sl_left = stereo_data_sl[:, 0]  # Extract left channel
  106.         sl_right = stereo_data_sl[:, 1]  # Extract right channel    
  107.         sr_left = stereo_data_sr[:, 0]  # Extract left channel
  108.         sr_right = stereo_data_sr[:, 1]  # Extract right channel
  109.        
  110.         # Create a 14-channel file by combining left and right channels
  111.         # Here we'll duplicate the left and right channels to create a 14-channel file
  112.         fourteen_channel_data = [fl_left, fl_right, sl_left, sl_right, rl_left, rl_right, fc_left, fr_right, fr_left, sr_right, sr_left, rr_right, rr_left, fc_right]
  113.        
  114.         # Reshape the data into a 14-channel format
  115.         fourteen_channel_data = list(map(list, zip(*fourteen_channel_data)))  # Interleave the channels
  116.        
  117.         # Save the 14-channel audio data
  118.         sf.write(output_filename + '.wav', fourteen_channel_data, samplerate_0, format='WAV', subtype='PCM_24')
  119.         return 0    # Generation finished without errors
  120.        
  121.  
  122.  
  123. # Function to open file explorer and update the corresponding entry field
  124. def open_file_explorer(entry):
  125.     file_path = filedialog.askopenfilename(title="Select wav file", filetypes=[("WAV files", "*.wav;*.wave")])
  126.     entry.delete(0, tk.END)
  127.     entry.insert(0, file_path)
  128.  
  129. message_colors = ["blue", "green"]
  130. color_index = 0
  131. message_label = None
  132.  
  133. # Function to handle the conversion
  134. def convert_files():
  135.     global color_index
  136.     global message_label
  137.     output_filename = output_filename_entry.get() or "output"
  138.     paths = [entry.get() or "None" for entry in entry_fields]
  139.  
  140.     message = generate_hrir_file(paths, output_filename)
  141.    
  142.     # Clear the previous completion message, if exists
  143.     if message_label is not None:
  144.         message_label.destroy()
  145.    
  146.     if message == 0:
  147.         # Add a message on the GUI to inform the user that the file generation is complete
  148.         message_label = tk.Label(root, text="File generation completed!", fg=message_colors[color_index])
  149.         message_label.pack()
  150.         # Update the color index for the next message
  151.         color_index = (color_index + 1) % len(message_colors)
  152.     if message == 1:
  153.         # error 1
  154.         message_label = tk.Label(root, text="Not a supported speaker configuration", fg="red")
  155.         message_label.pack()
  156.     if message == 2:
  157.         # error 2
  158.         message_label = tk.Label(root, text="Wrong channel configuration for stereo", fg="red")
  159.         message_label.pack()
  160.     if message == 3:
  161.         # error 3
  162.         message_label = tk.Label(root, text="One of the files was not in stereo format", fg="red")
  163.         message_label.pack()
  164.     if message == 4:
  165.         # error 4
  166.         message_label = tk.Label(root, text="Files do not have the same sample rate", fg="red")
  167.         message_label.pack()
  168.     if message == 5:
  169.         # error 4
  170.         message_label = tk.Label(root, text="Wrong channel for HeSUVi to stereo conversion", fg="red")
  171.         message_label.pack()
  172.     if message == 6:
  173.         # error 4
  174.         message_label = tk.Label(root, text="HeSuVi file does not have 14 channels", fg="red")
  175.         message_label.pack()
  176.    
  177. # Creating the main application window
  178. root = tk.Tk()
  179. root.title("IR wav HRIR Converter")
  180.  
  181. # List to store entry fields and their respective names
  182. entry_fields = []
  183. field_names = ["HeSuVi", "Left", "Right", "Center", "Left Rear", "Right Rear", "Left Side", "Right Side"]
  184.  
  185. # Function to create file input fields with respective names
  186. def create_file_input(name):
  187.     frame = tk.Frame(root)
  188.     frame.pack()
  189.     label = tk.Label(frame, text=f"{name}:")
  190.     label.pack(side=tk.LEFT)
  191.     entry = tk.Entry(frame, width=50)
  192.     entry.pack(side=tk.LEFT)
  193.     entry_fields.append(entry)
  194.     browse_button = tk.Button(frame, text="Browse", command=lambda: open_file_explorer(entry))
  195.     browse_button.pack(side=tk.LEFT)
  196.  
  197. # Create file input fields with respective names
  198. for name in field_names:
  199.     create_file_input(name)
  200.    
  201. # Entry field for the output file name
  202. output_filename_label = tk.Label(root, text="Output File Name:")
  203. output_filename_label.pack()
  204. output_filename_entry = tk.Entry(root, width=50)
  205. output_filename_entry.pack()
  206.  
  207. # Button to trigger the conversion process
  208. convert_button = tk.Button(root, text="Convert Files", command=convert_files)
  209. convert_button.pack()
  210.  
  211. # Run the application
  212. root.mainloop()
  213.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement