VapiLLM
03/21/2025, 7:51 PMReceived PCM data, buffer size: ${pcmBuffer.length}
);
} else {
console.log('Received message:', JSON.parse(data.toString()));
}
});
ws.on('close', () => {
if (pcmBuffer.length > 0) {
fs.writeFileSync('audio.pcm', pcmBuffer);
console.log('Audio data saved to audio.pcm');
}
});
ws.on('error', (error) => console.error('WebSocket error:', error));SlaviSavanovic
03/21/2025, 10:47 PMKyle
03/24/2025, 2:55 PMShubham Bajaj
03/24/2025, 10:18 PMbash
ffmpeg -f s16le -ar 16000 -ac 1 -i audio.pcm output.wav
This command specifies:
- `-f s16le`: The format is signed 16-bit little-endian PCM
- `-ar 16000`: The sample rate is 16kHz (based on Vapi's common settings)
- `-ac 1`: One audio channel (mono)
### Option 2: Modify your code to save as WAV directly
Here's an updated version of your code that will save the audio as a WAV file directly:
javascript
const WebSocket = require('ws');
const fs = require('fs');
let pcmBuffer = Buffer.alloc(0);
const ws = new WebSocket("");
ws.on('open', () => console.log('WebSocket connection established'));
ws.on('message', (data, isBinary) => {
if (isBinary) {
pcmBuffer = Buffer.concat([pcmBuffer, data]);
console.log(`Received PCM data, buffer size: ${pcmBuffer.length}`);
} else {
console.log('Received message:', JSON.parse(data.toString()));
}
});
ws.on('close', () => {
if (pcmBuffer.length > 0) {
// Define WAV parameters based on Vapi's PCM format
const sampleRate = 16000; // 16kHz is common for Vapi
const numChannels = 1; // Usually mono
const bitsPerSample = 16; // 16-bit PCM
const header = Buffer.alloc(44);
// RIFF chunk descriptor
header.write('RIFF', 0);
header.writeUInt32LE(36 + pcmBuffer.length, 4);
header.write('WAVE', 8);
header.write('fmt ', 12);
header.writeUInt32LE(16, 16);
header.writeUInt16LE(1, 20);
header.writeUInt16LE(numChannels, 22); // NumChannels
header.writeUInt32LE(sampleRate, 24);
header.writeUInt32LE(sampleRate * numChannels * bitsPerSample/8, 28);
header.writeUInt16LE(numChannels * bitsPerSample/8, 32);
header.writeUInt16LE(bitsPerSample, 34);
header.write('data', 36);
header.writeUInt32LE(pcmBuffer.length, 40);
const wavBuffer = Buffer.concat([header, pcmBuffer]);
fs.writeFileSync('audio.wav', wavBuffer);
console.log('Audio data saved to audio.wav');
}
});
ws.on('error', (error) => console.error('WebSocket error:', error));
This modified code adds a standard WAV header to your PCM data, making it playable in any audio player.Shubham Bajaj
03/24/2025, 10:18 PMVapiLLM
03/26/2025, 11:26 PMVapiLLM
03/26/2025, 11:26 PMKyle
03/29/2025, 11:44 AMVapiLLM
03/29/2025, 12:31 PMVapiLLM
03/29/2025, 12:32 PMVapiLLM
03/29/2025, 12:32 PMShubham Bajaj
03/30/2025, 11:08 AMpython
# Try these audio parameters
FORMAT = pyaudio.paInt16 # 16-bit PCM
CHANNELS = 1 # Mono
RATE = 24000 # Try 24kHz instead of 16kHz
CHUNK = 960 # For 24kHz, 40ms chunks (24000 * 0.04)
# Alternatively, try 8kHz
# RATE = 8000
# CHUNK = 320 # For 8kHz, 40ms chunks (8000 * 0.04)
In your on_message
function, you might need to add some buffering to ensure smooth playback:
python
def on_message(ws, message):
"""Handles incoming WebSocket messages."""
global buffer_list
if isinstance(message, bytes):
# Play the audio data directly
stream.write(message)
# For analysis, store the data
audio_data = np.frombuffer(message, dtype=np.int16)
# Apply a small amount of buffering (1-2 frames) for smoother playback
buffer_list.append(audio_data)
print(f"Playing PCM audio, received {len(message)} bytes")
# Save audio data when enough has accumulated
if len(buffer_list) * CHUNK >= window_size:
save_audio_window()
else:
print(f"Received message: {json.loads(message)}")
## For Playing Back Saved Files
If you want to play back the saved PCM files correctly, you need to use the same parameters when opening them:
python
# To play back your saved PCM files
from scipy.io.wavfile import write
import numpy as np
# Convert PCM to WAV with correct parameters
pcm_data = np.fromfile('your_saved_file.pcm', dtype=np.int16)
write('converted_file.wav', 24000, pcm_data) # Try 24kHz
## Recommendations
1. **Try different sample rates**: Start with 24kHz, then try 8kHz if that doesn't work.
2. **Check chunk size**: Make sure your chunk size matches the expected frame size for your sample rate.
3. **Add buffering**: A small buffer (1-2 frames) can help smooth out playback issues.
4. **FFmpeg conversion**: If you still have issues, try converting with FFmpeg:
ffmpeg -f s16le -ar 24000 -ac 1 -i audio.pcm output.wav
Please let me know if any of these adjustments help with the audio distortion, and I can further refine the solution.Ryan Opfer
04/01/2025, 1:32 AMRyan Opfer
04/01/2025, 3:38 AMKyle
04/01/2025, 10:06 PMaurelien-ldp
04/02/2025, 7:56 PMKyle
04/06/2025, 12:38 PMVapiLLM
04/23/2025, 1:39 AMKyle
04/24/2025, 12:11 PM