Add comprehensive logging for extra button debugging

Added detailed console logging throughout button functionality:

Startup logging:
- Shows if button is enabled/disabled
- Displays GPIO pin number and pressed state
- Shows configured button sound file path

Button press detection:
- Logs when button is pressed in main loop
- Logs when button is pressed during recording
- Shows recording/playing state

Button sound playback:
- File path and existence check
- Audio file properties (rate, channels, width)
- Sample rate mismatch warnings
- Playback progress (chunk count)
- Volume level
- Detailed error messages with traceback

Recording loop enhancement:
- Added button checking INSIDE recording loop
- Previously button only checked in main loop
- Button now works during active recording

All logs prefixed with [BUTTON] for easy filtering.

This helps diagnose why button sound isn't playing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-27 15:50:21 +07:00
parent 2ddba3f3e1
commit e2218a0c9a

View File

@@ -495,6 +495,15 @@ class RotaryPhone:
print("Handset hung up, stopping recording immediately")
break
# Check extra button during recording
if EXTRA_BUTTON_ENABLED and GPIO.input(EXTRA_BUTTON_PIN) == EXTRA_BUTTON_PRESSED:
print(f"[BUTTON] Button pressed during recording!")
if not self.extra_button_playing:
print(f"[BUTTON] Triggering button sound...")
button_thread = threading.Thread(target=self.play_extra_button_sound, daemon=True)
button_thread.start()
time.sleep(0.5) # Debounce to prevent multiple triggers
try:
data = stream.read(CHUNK, exception_on_overflow=False)
frames.append(data)
@@ -554,32 +563,45 @@ class RotaryPhone:
def play_extra_button_sound(self):
"""Play sound when extra button is pressed (only during recording)"""
if not EXTRA_BUTTON_ENABLED:
print("[BUTTON] Extra button disabled in config")
return
# Only play if currently recording
if not self.recording:
print("Extra button ignored - not recording")
print("[BUTTON] Extra button ignored - not recording")
return
button_sound = self.get_extra_button_sound_path()
print(f"[BUTTON] Button sound path: {button_sound}")
if not os.path.exists(button_sound):
print(f"Extra button sound not found: {button_sound}")
print(f"[BUTTON] ERROR: Sound file not found: {button_sound}")
return
print(f"\n=== Extra button pressed ===")
print(f"[BUTTON] Playing extra button sound...")
self.extra_button_playing = True
try:
# Use a separate PyAudio instance for playback during recording
# This allows simultaneous input (recording) and output (button sound)
print(f"[BUTTON] Opening audio file...")
audio_playback = pyaudio.PyAudio()
wf = wave.open(button_sound, 'rb')
file_rate = wf.getframerate()
file_channels = wf.getnchannels()
file_width = wf.getsampwidth()
print(f"[BUTTON] File info - Rate: {file_rate}Hz, Channels: {file_channels}, Width: {file_width}")
if file_rate != RATE:
print(f"[BUTTON] WARNING: File sample rate ({file_rate}Hz) != configured rate ({RATE}Hz)")
print(f"[BUTTON] Opening audio stream on device {AUDIO_DEVICE_INDEX}...")
stream = audio_playback.open(
format=audio_playback.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
format=audio_playback.get_format_from_width(file_width),
channels=file_channels,
rate=file_rate,
output=True,
output_device_index=AUDIO_DEVICE_INDEX,
frames_per_buffer=CHUNK
@@ -587,9 +609,12 @@ class RotaryPhone:
# Get volume multiplier
volume = self.get_volume() / 100.0
print(f"[BUTTON] Volume: {int(volume * 100)}%")
# Play the sound
print(f"[BUTTON] Starting playback...")
data = wf.readframes(CHUNK)
chunk_count = 0
while data:
# Apply volume
if volume < 1.0:
@@ -599,36 +624,48 @@ class RotaryPhone:
stream.write(data)
data = wf.readframes(CHUNK)
chunk_count += 1
stream.stop_stream()
stream.close()
wf.close()
audio_playback.terminate()
print("Extra button sound playback finished")
print(f"[BUTTON] Playback finished ({chunk_count} chunks)")
except Exception as e:
print(f"Error playing button sound: {e}")
print(f"[BUTTON] ERROR playing button sound: {e}")
import traceback
traceback.print_exc()
finally:
self.extra_button_playing = False
print(f"[BUTTON] Button playback complete")
def phone_loop(self):
"""Main phone handling loop"""
print("Rotary Phone System Started")
print(f"Hook pin: GPIO {HOOK_PIN}")
if EXTRA_BUTTON_ENABLED:
print(f"Extra button: GPIO {EXTRA_BUTTON_PIN}")
print(f"Extra button: ENABLED on GPIO {EXTRA_BUTTON_PIN}")
print(f"Extra button pressed state: {EXTRA_BUTTON_PRESSED} ({'LOW' if EXTRA_BUTTON_PRESSED == GPIO.LOW else 'HIGH'})")
print(f"Extra button sound: {self.get_extra_button_sound_path()}")
else:
print(f"Extra button: DISABLED")
print(f"Recordings will be saved to: {OUTPUT_DIR}")
try:
while True:
# Check extra button first (higher priority)
if EXTRA_BUTTON_ENABLED and GPIO.input(EXTRA_BUTTON_PIN) == EXTRA_BUTTON_PRESSED:
print(f"[BUTTON] Button pressed detected (recording={self.recording}, playing={self.extra_button_playing})")
if not self.extra_button_playing:
# Play extra button sound in a separate thread to not block
print(f"[BUTTON] Starting button sound thread...")
button_thread = threading.Thread(target=self.play_extra_button_sound, daemon=True)
button_thread.start()
time.sleep(0.5) # Debounce
else:
print(f"[BUTTON] Button sound already playing, ignoring")
# Wait for handset pickup
if GPIO.input(HOOK_PIN) == HOOK_PRESSED and self.phone_status == "on_hook":