MCPcopy Create free account
hub / github.com/Improbable-AI/VisionProTeleop / audio_file_streamer

Function audio_file_streamer

examples/08_stream_audio_file.py:88–156  ·  view source on GitHub ↗

Stream audio file in a loop

(audio_file_path, stereo=False)

Source from the content-addressed store, hash-verified

86
87
88def audio_file_streamer(audio_file_path, stereo=False):
89 """Stream audio file in a loop"""
90 from pydub import AudioSegment
91
92 print(f"🎵 Loading audio file: {audio_file_path}")
93
94 # Load audio file (supports MP3, WAV, etc.)
95 audio = AudioSegment.from_file(audio_file_path)
96
97 # Convert to 48kHz with specified channel count
98 channels = 2 if stereo else 1
99 audio = audio.set_frame_rate(48000).set_channels(channels)
100
101 channel_mode = "stereo" if stereo else "mono"
102 print(f"✓ Audio loaded ({channel_mode}):")
103 print(f" - Duration: {len(audio) / 1000:.2f} seconds")
104 print(f" - Sample rate: {audio.frame_rate} Hz")
105 print(f" - Channels: {audio.channels}")
106 print(f" - Sample width: {audio.sample_width} bytes")
107
108 # Get raw audio data as int16 samples
109 # For stereo, this array is interleaved: [L, R, L, R, L, R, ...]
110 audio_samples = np.array(audio.get_array_of_samples(), dtype=np.int16)
111 total_samples = len(audio_samples)
112
113 # Track position in audio file (in terms of individual samples, not frames)
114 current_position = 0
115
116 def generate_audio(audio_frame):
117 nonlocal current_position
118
119 # Number of samples per frame PER CHANNEL
120 num_samples_per_channel = audio_frame.samples
121
122 # Total samples needed (for stereo: num_samples * 2, for mono: num_samples * 1)
123 num_samples_needed = num_samples_per_channel * channels
124
125 # Extract samples for this frame
126 end_position = current_position + num_samples_needed
127
128 # Handle looping
129 if end_position >= total_samples:
130 # Wrap around to beginning
131 samples_before_end = total_samples - current_position
132 samples_after_wrap = num_samples_needed - samples_before_end
133
134 # Combine end + beginning
135 frame_data = np.concatenate([
136 audio_samples[current_position:],
137 audio_samples[:samples_after_wrap]
138 ])
139
140 current_position = samples_after_wrap
141 else:
142 # Normal case: extract from current position
143 frame_data = audio_samples[current_position:end_position]
144 current_position = end_position
145

Callers 1

Calls 1

printFunction · 0.50

Tested by

no test coverage detected