moedra
Member
Thread Starter
- Joined
- Mar 1, 2021
- Posts
- 148
Hi John. I need some help. I am not a coder, but I am trying to enlist the help of Gemini to write some macros for REW using the API and I am hitting a wall where REW will not release the data needed to make the macros function properly. The hard part is that I don't understand Python code or the API and therefore cannot troubleshoot. I've had Gemini scan this entire forum for anything that can be of assistance, and although we've learned a lot, this macro still doesn't fully work the way it's meant to (hands-free). Gemini even tried having the entire thing done in Python code, but REW won't release the measurement data, and it won't save out files in the scripts, so data cannot be extracted that way either...
In this first macro (of maybe four or five), I want to:
1. take the main measurements, which I'm calling Measurement-L and Measurement-R, and smooth them to 1/6
2. copy them via response copy, resulting in Measurement-L-copy and Measurement-R-copy
3. smooth both copies to 1/12
4. generate RMS Average measurement of Measurement-L and Measurement-L-copy, resulting in RMS Average 1
5. generate RMS Average measurement of Measurement-R and Measurement-R-copy, resulting in RMS Average 2
6. export RMS Average 1 as text, with no smoothing, max frequency capped to 22kHz, to filename Main-L.txt
7. export RMS Average 2 as text, with no smoothing, max frequency capped to 22kHz, to filename Main-R.txt
8. import Main-L and Main-R back into REW
9. generate minimum phase copies (new measurement versions) of Main-L and Main-R, resulting in Main-L-MP and Main-R-MP
10. delete/remove the copies and the RMS averages, as they are not needed any further
The objective of this macro is to have Main-L, Main-L-MP, Main-R, and Main-R-MP prepared for further operations in the following regard:
• They contain the relative smoothing value of 1/9, yet they are not smoothed as far as REW is concerned.
• The raw data is "smoothed", so subsequent arithmetic can be performed on the smoothed data rather than the original raw measurement data.
Of course, if 1/9 were an option I'd just smooth to that and be done with it, but this is great exercise to have a macro do, so I'm doing it!
The problem is that not all of these steps work correctly, and Gemini is having a hard time figuring out how to get the API to do what is being asked. Here's breakdown of what is and isn't working:
1. works great. 1/6 smoothed L and R
2. response copy works great
3. this works. same as step 1
4 and 5. This does not work. In the script I have resorted to having Gemini code this as a user step, so I have to generate the RMS average measurements manually
6 and 7. This does not work either. We've been able to get the parameters set but REW will not export any files. This has become another manual operation.
8. same as the last step, REW will not import the files I made (Main-L.txt and Main-R.txt). Another manual operation. The script waits for me to import the files, then continues.
9. this step works
10. this does not work properly. Seemingly random measurements got removed and so this, too, has become a manual operation
So, the macro has too many user prompts, and the solution is simply a matter of getting REW to generate the average measurements and export/import the files so that the macro can be completely hands-free. The idea is to make this automatic so that it's faster, and also easier for someone who has no patience to do everything manually!
And I like the idea of making macros, since the later steps of my overall procedure are full of time-consuming arithmetic functions that have to executed in sequence for both speakers' measurements.
The script for "macro 1" is here.
For reference, "V3.1 minimum phase logic" refers to the version of the script in which we successfully got it to generate the minimum phase versions we asked for, so we made it a point to use that code because it was proven to work.
======================
import urllib.request
import json
import time
REW_URL = "http://127.0.0.1:4735"
def send_rew_request(endpoint, data=None, method='POST'):
url = f"{REW_URL}{endpoint}"
headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
try:
req_data = json.dumps(data).encode('utf-8') if data else None
req = urllib.request.Request(url, data=req_data, headers=headers, method=method)
with urllib.request.urlopen(req) as response:
return json.loads(response.read().decode('utf-8'))
except Exception: return None
def get_id(name):
# Quick check for ID
data = send_rew_request("/measurements", method='GET') or {}
for m_id, m_info in data.items():
if m_info.get('title') == name: return m_id
return None
def run_prep(name):
print(f" [+] Prepping {name} (Smooth 1/6 + Copy + Smooth 1/12)...")
sid = get_id(name)
if not sid:
print(f" [!] Error: {name} not found.")
return
# 1. Smooth Source to 1/6
send_rew_request(f"/measurements/{sid}/command", {"command": "Smooth", "parameters": [["smoothing", "1/6"]]})
# 2. Create Copy
send_rew_request(f"/measurements/{sid}/command", {"command": "Response copy"})
time.sleep(1) # Short pause to let copy register
# 3. Find and Smooth Copy to 1/12
# We check standard name variations for the copy
cid = get_id(f"{name}-copy") or get_id("Response copy") or get_id(f"{name} copy")
if cid:
send_rew_request(f"/measurements/{cid}/command", {"command": "Smooth", "parameters": [["smoothing", "1/12"]]})
else:
print(f" [!] Warning: Could not auto-smooth the copy for {name}. Please check it.")
def wait_for_import_and_finalize(target_name):
print(f"\n [...] Watching for '{target_name}' to appear in REW...")
# INFINITE LOOP: This prevents the script from failing if you take your time.
found_id = None
while not found_id:
found_id = get_id(target_name)
if not found_id:
time.sleep(2) # Poll every 2 seconds
print(f" [+] {target_name} detected! Applying V3.1 Minimum Phase logic...")
# THE PROVEN V3.1 COMMAND
send_rew_request(f"/measurements/{found_id}/command", {
"command": "Minimum phase version",
"parameters": [
["append lf tail", "false"], ["append hf tail", "false"],
["include cal", "false"], ["replicate data", "false"],
["apply frequency warping to hf tail", "false"]
]
})
# Verify it worked
time.sleep(1)
print(f" [√] {target_name} processing complete.")
if __name__ == "__main__":
print("--- PHASE 1: AUTOMATED PREP ---")
run_prep("Measurement-L")
run_prep("Measurement-R")
print("\n" + "="*60)
print(" PHASE 2: MANUAL INTERVENTION (The Missing Link)")
print(" 1. Go to 'All SPL' tab.")
print(" 2. Average 'Measurement-L' + Copy -> Export/Import as 'Main-L'")
print(" 3. Average 'Measurement-R' + Copy -> Export/Import as 'Main-R'")
print(" (The script is strictly waiting for 'Main-L' and 'Main-R' to appear)")
print("="*60)
# These functions will block (wait) until they see the files.
# They effectively act as the "Second Half" of the automation.
wait_for_import_and_finalize("Main-L")
wait_for_import_and_finalize("Main-R")
print("\nMacro 1 Complete. Safe to manually delete temp copies/averages.")
In this first macro (of maybe four or five), I want to:
1. take the main measurements, which I'm calling Measurement-L and Measurement-R, and smooth them to 1/6
2. copy them via response copy, resulting in Measurement-L-copy and Measurement-R-copy
3. smooth both copies to 1/12
4. generate RMS Average measurement of Measurement-L and Measurement-L-copy, resulting in RMS Average 1
5. generate RMS Average measurement of Measurement-R and Measurement-R-copy, resulting in RMS Average 2
6. export RMS Average 1 as text, with no smoothing, max frequency capped to 22kHz, to filename Main-L.txt
7. export RMS Average 2 as text, with no smoothing, max frequency capped to 22kHz, to filename Main-R.txt
8. import Main-L and Main-R back into REW
9. generate minimum phase copies (new measurement versions) of Main-L and Main-R, resulting in Main-L-MP and Main-R-MP
10. delete/remove the copies and the RMS averages, as they are not needed any further
The objective of this macro is to have Main-L, Main-L-MP, Main-R, and Main-R-MP prepared for further operations in the following regard:
• They contain the relative smoothing value of 1/9, yet they are not smoothed as far as REW is concerned.
• The raw data is "smoothed", so subsequent arithmetic can be performed on the smoothed data rather than the original raw measurement data.
Of course, if 1/9 were an option I'd just smooth to that and be done with it, but this is great exercise to have a macro do, so I'm doing it!
The problem is that not all of these steps work correctly, and Gemini is having a hard time figuring out how to get the API to do what is being asked. Here's breakdown of what is and isn't working:
1. works great. 1/6 smoothed L and R
2. response copy works great
3. this works. same as step 1
4 and 5. This does not work. In the script I have resorted to having Gemini code this as a user step, so I have to generate the RMS average measurements manually
6 and 7. This does not work either. We've been able to get the parameters set but REW will not export any files. This has become another manual operation.
8. same as the last step, REW will not import the files I made (Main-L.txt and Main-R.txt). Another manual operation. The script waits for me to import the files, then continues.
9. this step works
10. this does not work properly. Seemingly random measurements got removed and so this, too, has become a manual operation
So, the macro has too many user prompts, and the solution is simply a matter of getting REW to generate the average measurements and export/import the files so that the macro can be completely hands-free. The idea is to make this automatic so that it's faster, and also easier for someone who has no patience to do everything manually!
And I like the idea of making macros, since the later steps of my overall procedure are full of time-consuming arithmetic functions that have to executed in sequence for both speakers' measurements.
The script for "macro 1" is here.
For reference, "V3.1 minimum phase logic" refers to the version of the script in which we successfully got it to generate the minimum phase versions we asked for, so we made it a point to use that code because it was proven to work.
======================
import urllib.request
import json
import time
REW_URL = "http://127.0.0.1:4735"
def send_rew_request(endpoint, data=None, method='POST'):
url = f"{REW_URL}{endpoint}"
headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
try:
req_data = json.dumps(data).encode('utf-8') if data else None
req = urllib.request.Request(url, data=req_data, headers=headers, method=method)
with urllib.request.urlopen(req) as response:
return json.loads(response.read().decode('utf-8'))
except Exception: return None
def get_id(name):
# Quick check for ID
data = send_rew_request("/measurements", method='GET') or {}
for m_id, m_info in data.items():
if m_info.get('title') == name: return m_id
return None
def run_prep(name):
print(f" [+] Prepping {name} (Smooth 1/6 + Copy + Smooth 1/12)...")
sid = get_id(name)
if not sid:
print(f" [!] Error: {name} not found.")
return
# 1. Smooth Source to 1/6
send_rew_request(f"/measurements/{sid}/command", {"command": "Smooth", "parameters": [["smoothing", "1/6"]]})
# 2. Create Copy
send_rew_request(f"/measurements/{sid}/command", {"command": "Response copy"})
time.sleep(1) # Short pause to let copy register
# 3. Find and Smooth Copy to 1/12
# We check standard name variations for the copy
cid = get_id(f"{name}-copy") or get_id("Response copy") or get_id(f"{name} copy")
if cid:
send_rew_request(f"/measurements/{cid}/command", {"command": "Smooth", "parameters": [["smoothing", "1/12"]]})
else:
print(f" [!] Warning: Could not auto-smooth the copy for {name}. Please check it.")
def wait_for_import_and_finalize(target_name):
print(f"\n [...] Watching for '{target_name}' to appear in REW...")
# INFINITE LOOP: This prevents the script from failing if you take your time.
found_id = None
while not found_id:
found_id = get_id(target_name)
if not found_id:
time.sleep(2) # Poll every 2 seconds
print(f" [+] {target_name} detected! Applying V3.1 Minimum Phase logic...")
# THE PROVEN V3.1 COMMAND
send_rew_request(f"/measurements/{found_id}/command", {
"command": "Minimum phase version",
"parameters": [
["append lf tail", "false"], ["append hf tail", "false"],
["include cal", "false"], ["replicate data", "false"],
["apply frequency warping to hf tail", "false"]
]
})
# Verify it worked
time.sleep(1)
print(f" [√] {target_name} processing complete.")
if __name__ == "__main__":
print("--- PHASE 1: AUTOMATED PREP ---")
run_prep("Measurement-L")
run_prep("Measurement-R")
print("\n" + "="*60)
print(" PHASE 2: MANUAL INTERVENTION (The Missing Link)")
print(" 1. Go to 'All SPL' tab.")
print(" 2. Average 'Measurement-L' + Copy -> Export/Import as 'Main-L'")
print(" 3. Average 'Measurement-R' + Copy -> Export/Import as 'Main-R'")
print(" (The script is strictly waiting for 'Main-L' and 'Main-R' to appear)")
print("="*60)
# These functions will block (wait) until they see the files.
# They effectively act as the "Second Half" of the automation.
wait_for_import_and_finalize("Main-L")
wait_for_import_and_finalize("Main-R")
print("\nMacro 1 Complete. Safe to manually delete temp copies/averages.")
Last edited:






