#missing flush_id in chunks message

1 messages · Page 1 of 1 (latest)

hardy vigil
#

Hi All, when using flushing on websockets, should flush_id be included in the chunk packets? I don't see it. How to I match the audio data up with the flush_id?

hexed jewelBOT
#

Hey Ryan! Looping in @severe plaza to answer your question around flushing

severe plaza
#

Hi @hardy vigil - I believe each chunk should have a flush_id in the response yep. Is that not what you’re seeing? 👀

hardy vigil
#

hey @severe plaza looking through the raw responses, it appears that flush_id is indeed coming back, however, it always has a value of zero

severe plaza
#

Hey @hardy vigil - that's expected in the sense that unless you flush overtly all generations will be part of the same flush_id. You can see more information about that here

hardy vigil
#

i'm flushing after each sentence in a paragraph in order to send the audio back a sentence at a time while using the same context @severe plaza

severe plaza
#

Hm Can you share a code snippet @hardy vigil

hardy vigil
#

we're in golang...
`requests := make([]cartesiaRequest, 0)

request := cartesiaRequest{
    ModelId:    config.Model,
    Transcript: ttsInput.Transcript,
    Voice: cartesiaVoice{
        Mode: "id",
        Id:   voice,
    },
    OutputFormat: cartesiaOutput{
        Container:  "raw",
        Encoding:   encodingPCM_S16LE,
        SampleRate: 16000,
    },
    ContextId:            contextId,
    Continue:             true,
    Flush:                false,
    AddTimestamps:        true,
    AddPhonemeTimestamps: true,
}
requests = append(requests, request)

flushRequest := cartesiaRequest{
    ModelId:    config.Model,
    Transcript: "",
    Voice: cartesiaVoice{
        Mode: "id",
        Id:   voice,
    },
    OutputFormat: cartesiaOutput{
        Container:  "raw",
        Encoding:   encodingPCM_S16LE,
        SampleRate: 16000,
    },
    ContextId: contextId,
    Continue:  true,
    Flush:     true,
}
requests = append(requests, flushRequest)

slog.InfoContext(ctx, fmt.Sprintf("[CARTESIA] sending tts request: %+v", request))

for _, request := range requests {
    msg, err := json.Marshal(request)
    if err != nil {
        slog.ErrorContext(ctx, fmt.Sprintf("[CARTESIA] error on marshalling tts request: %v", err))
        return err
    }

    c.ws.Write(ctx, websocket.MessageText, msg)
}`
#

Here is the type def for the request:

type cartesiaRequest struct { ModelId string json:"model_id" Transcript string json:"transcript" Voice cartesiaVoice json:"voice" OutputFormat cartesiaOutputjson:"output_format" Language string json:"language,omitempty" Duration float64 json:"duration,omitempty" ContextId string json:"context_id,omitempty" Continue bool json:"continue,omitempty" MaxBufferDelayMs int json:"max_buffer_delay_ms,omitempty" Flush bool json:"flush,omitempty" AddTimestamps bool json:"add_timestamps,omitempty" AddPhonemeTimestamps bool json:"add_phoneme_timestamps,omitempty" }

#

Here is a snippet of our read routine which parses the chunk messsages...

`func (c *websocketClient) readMessage(ctx context.Context, raw []byte) (*scenestream.TtsOutput, error) {
var base baseMsg
if err := json.Unmarshal(raw, &base); err != nil {
return nil, err
}

switch base.Type {
case "chunk":
    var m chunkMsg
    err := json.Unmarshal(raw, &m)
    if err == nil {
        constructing := c.baseMessageForContextId(m.ContextID, c.flushId)
        handleChunk(m, &constructing)
        m.Data = "" // Clear the data to avoid memory leaks
        slog.InfoContext(ctx, fmt.Sprintf("[CARTESIA] received chunk: %v", m)) //flush id is always zero
        return &constructing, nil
    } else {
        return nil, err
    }`
#

here is the chunkMessage type def...

type chunkMsg struct { Type string json:"type" Data string json:"data" Done bool json:"done" StatusCode int json:"status_code" ContextID string json:"context_id" FlushID int json:"flush_id,omitempty" StepTime *float64json:"step_time,omitempty" }