Modulate · AsyncAPI Specification
Velma 2 Music Detection Streaming API
Version 0.0.0
Real-time frame-level music and speech classification over WebSocket. The client streams audio and receives per-frame probabilities as they become available, followed by a final summary on completion.
View Spec
View on GitHub
CompanyAiVoice AISpeech to TextTranscriptionDeepfake DetectionContent ModerationTrust and SafetyAudioMachine LearningPII RedactionVoice IntelligenceAsyncAPIWebhooksEvents
Channels
streaming-detection
## WebSocket Close Codes - `1000`: Normal closure after the `done` message, or after the connection completes. - `1003`: Invalid or missing query parameters (unknown `audio_format`, invalid `sample_rate` or `num_channels`, a raw format missing `sample_rate`/`num_channels`, `sample_rate`/`num_channels` supplied without `audio_format`, or `audio_format` omitted). An `error` message is sent before the close. - `4002`: The audio could not be decoded, or does not match the declared raw `audio_format`. An `error` message is sent before the close. - `4003`: The request could not be validated, or the request is not permitted. An `error` message is sent before the close. - `4029`: The request could not be completed due to insufficient credits. An `error` message is sent before the close.
Messages
✉
audioData
Audio Data
A binary frame containing audio samples.
✉
endOfStream
End of Stream
An empty text frame signalling that the client has finished sending audio.
✉
frameResult
Frame Result
A single 192-millisecond frame detection result.
✉
done
Done
Analysis complete - all frame results have been delivered.
✉
error
Error
An error occurred during connection or analysis.
Servers
wss
production
Modulate Music Detection Streaming Server
AsyncAPI Specification
asyncapi: 3.0.0
info:
title: Velma 2 Music Detection Streaming API
version: 0.0.0
description: |
Real-time frame-level music and speech classification over WebSocket.
The client streams audio and receives per-frame probabilities as they
become available, followed by a final summary on completion.
servers:
production:
host: platform.modulate.ai
protocol: wss
description: Modulate Music Detection Streaming Server
channels:
streaming-detection:
address: /api/velma-2-music-detection-streaming
description: |
## WebSocket Close Codes
- `1000`: Normal closure after the `done` message, or after the
connection completes.
- `1003`: Invalid or missing query parameters (unknown `audio_format`,
invalid `sample_rate` or `num_channels`, a raw format missing
`sample_rate`/`num_channels`, `sample_rate`/`num_channels` supplied
without `audio_format`, or `audio_format` omitted). An `error` message
is sent before the close.
- `4002`: The audio could not be decoded, or does not match the
declared raw `audio_format`. An `error` message is sent before the
close.
- `4003`: The request could not be validated, or the request is not
permitted. An `error` message is sent before the close.
- `4029`: The request could not be completed due to insufficient credits.
An `error` message is sent before the close.
bindings:
ws:
query:
type: object
required:
- api_key
- audio_format
properties:
api_key:
type: string
description: API key used for authentication and usage tracking.
audio_format:
type: string
description: |
Audio encoding format. Required for all connections. Raw formats
(headerless samples) also require `sample_rate` and
`num_channels`; container formats carry that metadata in the
stream, so those parameters must not be supplied.
enum:
- s8
- s16le
- s16be
- s24le
- s24be
- s32le
- s32be
- u8
- u16le
- u16be
- u24le
- u24be
- u32le
- u32be
- f32le
- f32be
- f64le
- f64be
- mulaw
- alaw
- wav
- mp3
- ogg
- flac
- webm
- aac
- aiff
examples:
- s16le
- f32le
- mulaw
- webm
sample_rate:
type: integer
description: |
Sample rate in Hz. **Required** when `audio_format` is a raw
format. Not required and ignored for container formats. Must
not be specified without `audio_format`.
enum:
- 8000
- 11025
- 16000
- 22050
- 32000
- 44100
- 48000
- 96000
examples:
- 16000
- 48000
num_channels:
type: integer
description: |
Number of audio channels. **Required** when `audio_format` is
a raw format. Must be between 1 and 8. Must not be specified
for container formats, and must not be specified without
`audio_format`.
minimum: 1
maximum: 8
examples:
- 1
- 2
messages:
audioData:
$ref: '#/components/messages/audioData'
endOfStream:
$ref: '#/components/messages/endOfStream'
frameResult:
$ref: '#/components/messages/frameResult'
done:
$ref: '#/components/messages/done'
error:
$ref: '#/components/messages/error'
operations:
sendAudio:
action: send
channel:
$ref: '#/channels/streaming-detection'
summary: Stream audio data to the server.
description: |
Send binary frames containing audio data in the format declared by
the `audio_format` query parameter. Frames can be any size; the
server buffers and windows internally.
messages:
- $ref: '#/channels/streaming-detection/messages/audioData'
signalEnd:
action: send
channel:
$ref: '#/channels/streaming-detection'
summary: Signal end of audio stream.
description: |
Send an empty text frame (`""`) to indicate all audio has been sent.
The server will process any remaining buffered audio, deliver final
frame results, and send a `done` message.
messages:
- $ref: '#/channels/streaming-detection/messages/endOfStream'
receiveFrameResult:
action: receive
channel:
$ref: '#/channels/streaming-detection'
summary: Receive a per-frame detection result.
description: |
Emitted for each completed 192-millisecond frame. Results arrive in
chronological order but are streamed incrementally as inference
completes.
messages:
- $ref: '#/channels/streaming-detection/messages/frameResult'
receiveDone:
action: receive
channel:
$ref: '#/channels/streaming-detection'
summary: Receive the final summary when analysis is complete.
description: |
Sent after all frame results have been delivered, in response to the
client's end-of-stream signal. The server closes the connection after
this message.
messages:
- $ref: '#/channels/streaming-detection/messages/done'
receiveError:
action: receive
channel:
$ref: '#/channels/streaming-detection'
summary: Receive an error notification.
description: |
Sent if the connection parameters are invalid, the audio data does
not match the declared format, inference fails, or the server
encounters an internal error. The server closes the connection after
this message.
messages:
- $ref: '#/channels/streaming-detection/messages/error'
components:
messages:
audioData:
name: audioData
title: Audio Data
summary: A binary frame containing audio samples.
contentType: application/octet-stream
payload:
type: string
format: binary
description: |
Audio data in the format declared by the `audio_format` query
parameter. For raw formats this is headerless samples; for
container formats this is the encoded byte stream. Frames may
be any size; the server buffers internally.
endOfStream:
name: endOfStream
title: End of Stream
summary: >-
An empty text frame signalling that the client has finished sending
audio.
contentType: text/plain
payload:
type: string
const: ''
frameResult:
name: frameResult
title: Frame Result
summary: A single 192-millisecond frame detection result.
contentType: application/json
payload:
$ref: '#/components/schemas/FrameResultMessage'
done:
name: done
title: Done
summary: Analysis complete - all frame results have been delivered.
contentType: application/json
payload:
$ref: '#/components/schemas/DoneMessage'
error:
name: error
title: Error
summary: An error occurred during connection or analysis.
contentType: application/json
payload:
$ref: '#/components/schemas/ErrorResponse'
schemas:
FrameResultMessage:
type: object
required:
- type
- frame
properties:
type:
type: string
const: frame
frame:
$ref: '#/components/schemas/Frame'
Frame:
type: object
required:
- start_time_ms
- end_time_ms
- music_prob
- speech_prob
properties:
start_time_ms:
type: integer
minimum: 0
description: Frame start time in the original audio stream, in milliseconds.
examples:
- 0
end_time_ms:
type: integer
minimum: 0
description: |
Frame end time in the original audio stream, in milliseconds.
Each frame spans 192 milliseconds.
examples:
- 192
music_prob:
type: number
format: double
minimum: 0
maximum: 1
description: |
Probability that this frame contains music, rounded to four
decimal places. Independent of `speech_prob`.
examples:
- 0.0213
speech_prob:
type: number
format: double
minimum: 0
maximum: 1
description: |
Probability that this frame contains speech, rounded to four
decimal places. Independent of `music_prob`; music and speech
are not mutually exclusive (e.g. music with vocals).
examples:
- 0.9888
DoneMessage:
type: object
required:
- type
- duration_ms
- frame_count
- music_pct
- speech_pct
- primary_label
properties:
type:
type: string
const: done
duration_ms:
type: integer
minimum: 0
description: Total duration of the streamed audio processed, in milliseconds.
examples:
- 15360
frame_count:
type: integer
minimum: 0
description: Total number of frame results delivered during the session.
examples:
- 80
music_pct:
type: number
format: double
minimum: 0
maximum: 100
description: |
Percentage of the analysed duration classified as music,
rounded to one decimal place. `0.0` when no audio was analysed.
examples:
- 42.5
speech_pct:
type: number
format: double
minimum: 0
maximum: 100
description: |
Percentage of the analysed duration classified as speech,
rounded to one decimal place. `0.0` when no audio was analysed.
examples:
- 57.5
primary_label:
type: string
enum:
- music
- speech
- neither
- unknown
description: |
The dominant classification across the analysed audio.
- `music` - music covers at least as much of the audio as
speech, and more than zero.
- `speech` - speech covers more of the audio than music, and
more than zero.
- `neither` - neither music nor speech reached the dominant
threshold for any portion of the audio.
- `unknown` - no audio was analysed (no frames produced).
examples:
- speech
ErrorResponse:
type: object
required:
- type
- error
properties:
type:
type: string
const: error
error:
type: string
description: Human-readable error description.
examples:
- Internal server error
- This request is not permitted.
- Insufficient credits.
- Unable to validate request. Please try again.
- Audio data does not match the declared audio_format.
- >-
Invalid audio_format='mp4'. Valid values: ['aac', 'aiff', 'alaw',
'f32be', 'f32le', 'f64be', 'f64le', 'flac', 'mp3', 'mulaw', 'ogg',
's16be', 's16le', 's24be', 's24le', 's32be', 's32le', 's8',
'u16be', 'u16le', 'u24be', 'u24le', 'u32be', 'u32le', 'u8', 'wav',
'webm']
- >-
Raw audio formats require sample_rate and num_channels query
parameters
- sample_rate and num_channels require audio_format to be specified
- >-
Invalid sample_rate=50000. Valid values: [8000, 11025, 16000,
22050, 32000, 44100, 48000, 96000]
- Invalid num_channels=12. Must be between 1 and 8
- >-
audio_format query parameter is required. Example:
audio_format=s16le&sample_rate=16000&num_channels=1