### Speex Full Encoder-Decoder Pipeline in C Source: https://context7.com/xiph/speex/llms.txt This C code demonstrates a complete Speex audio encoding and decoding pipeline. It initializes the encoder and decoder, configures parameters, processes frames, and handles potential packet loss. This example requires the Speex library to be installed. ```c #include #include #include #include #include int main() { // Configuration const SpeexMode *mode = &speex_nb_mode; int quality = 8; int sampling_rate = 8000; // Initialize encoder void *encoder = speex_encoder_init(mode); if (!encoder) { fprintf(stderr, "Failed to create encoder\n"); return 1; } SpeexBits enc_bits; speex_bits_init(&enc_bits); speex_encoder_ctl(encoder, SPEEX_SET_QUALITY, &quality); speex_encoder_ctl(encoder, SPEEX_SET_SAMPLING_RATE, &sampling_rate); int frame_size; speex_encoder_ctl(encoder, SPEEX_GET_FRAME_SIZE, &frame_size); printf("Frame size: %d samples\n", frame_size); // Initialize decoder void *decoder = speex_decoder_init(mode); if (!decoder) { fprintf(stderr, "Failed to create decoder\n"); speex_bits_destroy(&enc_bits); speex_encoder_destroy(encoder); return 1; } SpeexBits dec_bits; speex_bits_init(&dec_bits); int enh = 1; speex_decoder_ctl(decoder, SPEEX_SET_ENH, &enh); // Allocate buffers spx_int16_t *input = malloc(frame_size * sizeof(spx_int16_t)); spx_int16_t *output = malloc(frame_size * sizeof(spx_int16_t)); char *encoded_frame = malloc(200); if (!input || !output || !encoded_frame) { fprintf(stderr, "Memory allocation failed\n"); goto cleanup; } // Encode and decode multiple frames int num_frames = 10; for (int i = 0; i < num_frames; i++) { // Generate test input (440 Hz sine wave) for (int j = 0; j < frame_size; j++) { double t = (double)(i * frame_size + j) / sampling_rate; input[j] = (spx_int16_t)(10000.0 * sin(2.0 * 3.14159265 * 440.0 * t)); } // Encode speex_bits_reset(&enc_bits); int ret = speex_encode_int(encoder, input, &enc_bits); if (ret == 0) { printf("Frame %d: Not transmitted (DTX)\n", i); continue; } int nbytes = speex_bits_write(&enc_bits, encoded_frame, 200); int bitrate; speex_encoder_ctl(encoder, SPEEX_GET_BITRATE, &bitrate); printf("Frame %d: Encoded to %d bytes, bitrate: %d bps\n", i, nbytes, bitrate); // Decode speex_bits_read_from(&dec_bits, encoded_frame, nbytes); ret = speex_decode_int(decoder, &dec_bits, output); if (ret == 0) { printf("Frame %d: Decoded successfully\n", i); } else if (ret == -2) { fprintf(stderr, "Frame %d: Decode error - corrupt stream\n", i); } // output now contains decoded audio } // Demonstrate packet loss handling printf("\nSimulating packet loss...\n"); int decode_ret = speex_decode_int(decoder, NULL, output); printf("Decoded lost packet with concealment (ret=%d)\n", decode_ret); cleanup: // Cleanup free(input); free(output); free(encoded_frame); speex_bits_destroy(&enc_bits); speex_bits_destroy(&dec_bits); speex_encoder_destroy(encoder); speex_decoder_destroy(decoder); printf("\nEncoding/decoding completed successfully\n"); return 0; } ``` -------------------------------- ### SDP fmtp for Multiple Speex Parameters Source: https://github.com/xiph/speex/blob/master/doc/draft-herlein-speex-rtp-profile-02.txt This example demonstrates combining multiple Speex-specific parameters within a single 'a=fmtp' line in SDP, separated by semicolons. It shows setting the mode to 'any' and enabling perceptual enhancement. ```sdp a=fmtp:97 mode=any;penh=1 ``` -------------------------------- ### SpeexBits Initialization and Data Packing in C Source: https://context7.com/xiph/speex/llms.txt Demonstrates initializing SpeexBits structures using dynamic allocation or a pre-allocated buffer. It shows how to pack various data types (integers) into a bitstream and then unpack them. Includes examples of peeking at bits and checking remaining bits. ```c #include #include void bits_manipulation_example() { SpeexBits bits; // Method 1: Initialize with dynamic allocation speex_bits_init(&bits); // Pack various data types speex_bits_pack(&bits, 0x1F, 5); // Pack 5 bits speex_bits_pack(&bits, 127, 7); // Pack 7 bits speex_bits_pack(&bits, 0xFFFF, 16); // Pack 16 bits // Get number of bytes used int nbytes = speex_bits_nbytes(&bits); printf("Packed data uses %d bytes\n", nbytes); // Write to buffer char buffer[100]; int written = speex_bits_write(&bits, buffer, 100); printf("Written %d bytes to buffer\n", written); speex_bits_destroy(&bits); // Method 2: Initialize with pre-allocated buffer SpeexBits bits2; char static_buffer[200]; speex_bits_init_buffer(&bits2, static_buffer, 200); speex_bits_pack(&bits2, 0xABCD, 16); // Method 3: Set bit buffer for reading (zero-copy) SpeexBits bits3; speex_bits_init(&bits3); speex_bits_set_bit_buffer(&bits3, buffer, written); // Read data back speex_bits_rewind(&bits3); unsigned int val1 = speex_bits_unpack_unsigned(&bits3, 5); unsigned int val2 = speex_bits_unpack_unsigned(&bits3, 7); unsigned int val3 = speex_bits_unpack_unsigned(&bits3, 16); printf("Unpacked: 0x%X, %d, 0x%X\n", val1, val2, val3); // Peek without advancing speex_bits_rewind(&bits3); unsigned int peek_val = speex_bits_peek_unsigned(&bits3, 5); printf("Peeked: 0x%X\n", peek_val); // Check remaining bits int remaining = speex_bits_remaining(&bits3); printf("Remaining bits: %d\n", remaining); speex_bits_destroy(&bits2); speex_bits_destroy(&bits3); } ``` -------------------------------- ### SDP fmtp for Perceptual Enhancement in Speex Source: https://github.com/xiph/speex/blob/master/doc/draft-herlein-speex-rtp-profile-02.txt This example shows how to use the 'a=fmtp' directive to suggest enabling the perceptual enhancement filter for the Speex decoder. Setting 'penh=1' indicates that perceptual enhancement is recommended. ```sdp m=audio 8088 RTP/AVP 97 a=rtpmap:97 speex/8000 a=fmtp:97 penh=1 ``` -------------------------------- ### Speex Speech Encoding Example Source: https://github.com/xiph/speex/blob/master/doc/programming.html Demonstrates the process of encoding speech frames using the Speex library. It includes initialization of SpeexBits and encoder state, setting the mode (narrowband or wideband), retrieving frame size, encoding individual frames, and freeing resources. Input is a float array representing audio, and output is a byte array of compressed data. ```c #include SpeexBits bits; void *enc_state; int frame_size; speex_bits_init(&bits); enc_state = speex_encoder_init(&speex_nb_mode); // Or &speex_wb_mode for wideband speex_encoder_ctl(enc_state, SPEEX_GET_FRAME_SIZE, &frame_size); // For each input frame: speex_bits_reset(&bits); speex_encode(enc_state, input_frame, &bits); nbBytes = speex_bits_write(&bits, byte_ptr, MAX_NB_BYTES); speex_bits_destroy(&bits); speex_encoder_destroy(enc_state); ``` -------------------------------- ### Speex Advanced Encoder Control Example (C) Source: https://context7.com/xiph/speex/llms.txt Illustrates fine-tuning Speex encoder parameters for specific requirements. This example shows how to set the sub-mode, enable high-pass filtering, configure packet loss concealment (PLC) tuning, reset the encoder state, get the lookahead duration, and control low/high band modes for wideband encoding. Requires the Speex library. ```c #include #include void advanced_encoder_control() { void *encoder = speex_encoder_init(&speex_wb_mode); // Set specific sub-mode (0-8 for narrowband, affects quality/bitrate) int submode = 6; speex_encoder_ctl(encoder, SPEEX_SET_MODE, &submode); // Get current sub-mode int current_submode; speex_encoder_ctl(encoder, SPEEX_GET_MODE, ¤t_submode); printf("Using sub-mode: %d\n", current_submode); // Enable high-pass filtering int highpass = 1; speex_encoder_ctl(encoder, SPEEX_SET_HIGHPASS, &highpass); // Set PLC tuning (packet loss concealment) int plc_tuning = 50; // Expected loss percentage speex_encoder_ctl(encoder, SPEEX_SET_PLC_TUNING, &plc_tuning); // Reset encoder state speex_encoder_ctl(encoder, SPEEX_RESET_STATE, NULL); // Get lookahead int lookahead; speex_encoder_ctl(encoder, SPEEX_GET_LOOKAHEAD, &lookahead); printf("Encoder lookahead: %d samples\n", lookahead); // For wideband: control low and high band modes separately int low_mode = 5; int high_mode = 6; speex_encoder_ctl(encoder, SPEEX_SET_LOW_MODE, &low_mode); speex_encoder_ctl(encoder, SPEEX_SET_HIGH_MODE, &high_mode); speex_encoder_destroy(encoder); } ``` -------------------------------- ### Example Speex Packet Structure Source: https://github.com/xiph/speex/blob/master/doc/draft-ietf-avt-rtp-speex-01-tmp.txt Illustrates the structure of an example RTP packet containing a single Speex frame with padding. ```APIDOC ## Example Speex Packet Structure ### Description Provides a visual representation of an RTP packet containing a single Speex frame and demonstrates how padding is applied to align the payload to an octet boundary. ### Method N/A (Illustrates packet structure, not an endpoint) ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example N/A ### Response #### Success Response (200) N/A #### Response Example N/A ### Example Packet Layout: This example shows an RTP packet with a single Speex frame and 5 bits of padding. ``` 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | RTP Header | +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | ..speex data.. | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ..speex data.. |0 1 1 1 1| +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ ``` - The packet begins with the standard RTP Header. - This is followed by the Speex encoded data (`..speex data..`). - The last octet contains 5 bits of padding (`0 1 1 1 1`) to ensure the payload ends on an octet boundary. ``` -------------------------------- ### SDP with Bandwidth Constraint for Speex Source: https://github.com/xiph/speex/blob/master/doc/draft-herlein-speex-rtp-profile-02.txt This example demonstrates how to apply a bandwidth limitation to a Speex audio offer in SDP. The 'b=AS:10' header restricts the bandwidth to 10 kbit/s, which should prompt the Speex encoder to use modes producing no more than this rate. This constraint applies to all payload types in the media line. ```sdp m=audio 8088 RTP/AVP 97 b=AS:10 a=rtpmap:97 speex/8000 ``` -------------------------------- ### Speex Speech Decoding Example Source: https://github.com/xiph/speex/blob/master/doc/programming.html Illustrates how to decode Speex-encoded speech frames. This involves initializing SpeexBits and the decoder state, setting the mode (narrowband or wideband), configuring optional post-filtering, reading encoded data, decoding the frame, and handling potential frame loss. Output is a float array representing decoded audio. ```c #include SpeexBits bits; void *dec_state; int frame_size; int pf = 1; // Enable post-filter speex_bits_init(&bits); dec_state = speex_decoder_init(&speex_nb_mode); // Or &speex_wb_mode for wideband speex_decoder_ctl(dec_state, SPEEX_GET_FRAME_SIZE, &frame_size); speex_decoder_ctl(dec_state, SPEEX_SET_PF, &pf); // For each input frame: speex_bits_read_from(&bits, input_bytes, nbBytes); speex_decode(dec_state, &bits, output_frame, 0); // 0 for normal, 1 for lost frame ``` -------------------------------- ### Speex Mode Selection and Querying Example (C) Source: https://context7.com/xiph/speex/llms.txt Demonstrates how to select and query different Speex codec modes for various bandwidths (narrowband, wideband, ultra-wideband). It shows direct mode access and retrieval by ID, and iterates through available modes to print their properties like frame size, sampling rate, and bitrate. Requires the Speex library. ```c #include void mode_selection_example() { // Method 1: Direct mode access const SpeexMode *nb_mode = &speex_nb_mode; // Narrowband 8 kHz const SpeexMode *wb_mode = &speex_wb_mode; // Wideband 16 kHz const SpeexMode *uwb_mode = &speex_uwb_mode; // Ultra-wideband 32 kHz // Method 2: Get mode by ID const SpeexMode *mode0 = speex_lib_get_mode(SPEEX_MODEID_NB); const SpeexMode *mode1 = speex_lib_get_mode(SPEEX_MODEID_WB); const SpeexMode *mode2 = speex_lib_get_mode(SPEEX_MODEID_UWB); // Query mode information printf("Available modes: %d\n", SPEEX_NB_MODES); for (int mode_id = 0; mode_id < SPEEX_NB_MODES; mode_id++) { const SpeexMode *mode = speex_lib_get_mode(mode_id); if (mode != NULL) { int frame_size; speex_mode_query(mode, SPEEX_MODE_FRAME_SIZE, &frame_size); printf("\nMode %d: %s\n", mode_id, mode->modeName); printf(" Mode ID: %d\n", mode->modeID); printf(" Frame size: %d samples\n", frame_size); printf(" Bitstream version: %d\n", mode->bitstream_version); // Create encoder to query more details void *enc = speex_encoder_init(mode); int sampling_rate; speex_encoder_ctl(enc, SPEEX_GET_SAMPLING_RATE, &sampling_rate); printf(" Sampling rate: %d Hz\n", sampling_rate); int bitrate; speex_encoder_ctl(enc, SPEEX_GET_BITRATE, &bitrate); printf(" Default bitrate: %d bps\n", bitrate); speex_encoder_destroy(enc); } } } ``` -------------------------------- ### Speex SDP fmtp Configuration Source: https://github.com/xiph/speex/blob/master/doc/draft-ietf-avt-rtp-speex-05-tmp.txt Demonstrates how to configure Speex parameters within an SDP 'a=fmtp' line, including modes, VBR, and comfort noise. ```APIDOC ## Speex SDP fmtp Configuration Examples This section details how to specify Speex codec parameters within the Session Description Protocol (SDP) using the `a=fmtp` attribute. ### a=fmtp:97 mode=1;mode=any;vbr=on **Description:** This example shows a single `a=fmtp` line with multiple Speex parameters separated by semicolons. It configures the codec to support mode 1, any mode, and enables variable bit rate (VBR). **Method:** N/A (SDP attribute) **Endpoint:** N/A (SDP attribute) **Parameters:** #### fmtp Parameters - **mode** (integer) - Optional - Specifies the preferred Speex encoding mode. Can be specified multiple times or as 'any'. - **vbr** (on/off/vad) - Optional - Enables or disables Variable Bit Rate encoding. 'vad' enables VBR with Voice Activity Detection. - **cng** (on/off) - Optional - Enables or disables Comfort Noise Generation. #### Request Example (SDP Snippet) ``` a=fmtp:97 mode=1;mode=any;vbr=on ``` #### Response Example N/A ``` ```APIDOC ## Example: Supporting All Modes, Prefer Mode 4 **Description:** This SDP example shows an offerer indicating a preference for Speex 'mode 4' while also signaling support for all available modes. The remote party may still choose a different mode based on its capabilities. **Method:** N/A (SDP Offer/Answer) **Endpoint:** N/A **Parameters:** #### SDP Parameters - **m=audio** - Specifies the media type and port. - **a=rtpmap** - Maps the payload type (97) to the Speex codec and sampling rate (8000 Hz). - **a=fmtp** - Configures Speex parameters: `mode=4` (preferred), `mode=any` (supports all). #### Request Example (SDP Snippet) ``` m=audio 8088 RTP/AVP 97 a=rtpmap:97 speex/8000 a=fmtp:97 mode=4;mode=any ``` #### Response Example N/A ``` ```APIDOC ## Example: Supporting Only Mode 3 and 5 **Description:** This SDP example demonstrates an offerer specifying that only Speex 'mode 3' and 'mode 5' are supported. The remote party must adhere to these specified modes. **Method:** N/A (SDP Offer/Answer) **Endpoint:** N/A **Parameters:** #### SDP Parameters - **m=audio** - Specifies the media type and port. - **a=rtpmap** - Maps the payload type (97) to the Speex codec and sampling rate (8000 Hz). - **a=fmtp** - Configures Speex parameters: `mode=3` and `mode=5` (only supported modes). #### Request Example (SDP Snippet) ``` m=audio 8088 RTP/AVP 97 a=rtpmap:97 speex/8000 a=fmtp:97 mode=3;mode=5 ``` #### Response Example N/A ``` ```APIDOC ## Example: Variable Bit Rate and Comfort Noise **Description:** This SDP example configures the Speex codec to use Variable Bit Rate (VBR) and enables Comfort Noise Generation (CNG). **Method:** N/A (SDP Offer/Answer) **Endpoint:** N/A **Parameters:** #### SDP Parameters - **m=audio** - Specifies the media type and port. - **a=rtpmap** - Maps the payload type (97) to the Speex codec and sampling rate (8000 Hz). - **a=fmtp** - Configures Speex parameters: `vbr=on` (enable VBR), `cng=on` (enable CNG). #### Request Example (SDP Snippet) ``` m=audio 8088 RTP/AVP 97 a=rtpmap:97 speex/8000 a=fmtp:97 vbr=on;cng=on ``` #### Response Example N/A ``` ```APIDOC ## Example: Voice Activity Detection (VAD) **Description:** This SDP example configures the Speex codec to utilize Voice Activity Detection (VAD) for silence suppression, often used in conjunction with VBR. **Method:** N/A (SDP Offer/Answer) **Endpoint:** N/A **Parameters:** #### SDP Parameters - **m=audio** - Specifies the media type and port. - **a=rtpmap** - Maps the payload type (97) to the Speex codec and sampling rate (8000 Hz). - **a=fmtp** - Configures Speex parameters: `vbr=vad` (enable VBR with VAD). #### Request Example (SDP Snippet) ``` m=audio 8088 RTP/AVP 97 a=rtpmap:97 speex/8000 a=fmtp:97 vbr=vad ``` #### Response Example N/A ``` ```APIDOC ## Example: Multiple Sampling Rates **Description:** This SDP example demonstrates how to offer Speex encoding at multiple sampling rates (16000 Hz and 8000 Hz) with specific mode preferences for each. **Method:** N/A (SDP Offer/Answer) **Endpoint:** N/A **Parameters:** #### SDP Parameters - **m=audio** - Specifies the media type and port. - **a=rtpmap** - Maps payload types (97, 98) to Speex codecs and sampling rates (16000 Hz, 8000 Hz). - **a=fmtp** - Configures Speex parameters for each payload type: `mode=10;mode=any` for 16kHz, `mode=7;mode=any` for 8kHz. #### Request Example (SDP Snippet) ``` m=audio 8088 RTP/AVP 97 98 a=rtpmap:97 speex/16000 a=fmtp:97 mode=10;mode=any a=rtpmap:98 speex/8000 a=fmtp:98 mode=7;mode=any ``` #### Response Example N/A ``` ```APIDOC ## Example: ptime and Multiple Speex Frames **Description:** This SDP example shows the use of the `a=ptime` attribute to specify the packetization interval, indicating how many milliseconds of audio are in each RTP packet. It's set to 40ms, implying two 20ms Speex frames per packet. **Method:** N/A (SDP Offer/Answer) **Endpoint:** N/A **Parameters:** #### SDP Parameters - **m=audio** - Specifies the media type and port. - **a=rtpmap** - Maps the payload type (97) to the Speex codec and sampling rate (8000 Hz). - **a=ptime** - Sets the packetization time to 40 milliseconds. This value should be a multiple of the Speex frame size (20ms). #### Request Example (SDP Snippet) ``` m=audio 8088 RTP/AVP 97 a=rtpmap:97 speex/8000 a=ptime:40 ``` **Note:** The `ptime` parameter applies to all payloads in the media line and is not part of `a=fmtp`. #### Response Example N/A ``` ```APIDOC ## Example: Complete Offer/Answer Exchange **Description:** This SDP example illustrates a complete Offer/Answer exchange where the offerer indicates support for Speex at both 16000 Hz and 8000 Hz sampling rates, implicitly supporting all modes as no specific modes are listed. **Method:** N/A (SDP Offer/Answer) **Endpoint:** N/A **Parameters:** #### SDP Parameters - **m=audio** - Specifies the media type and port. - **a=rtpmap** - Maps payload types (97, 98) to Speex codecs and sampling rates (16000 Hz, 8000 Hz). - **a=fmtp** - No mode specified for `a=fmtp`, indicating support for all modes. #### Request Example (SDP Snippet) ``` m=audio 8088 RTP/AVP 97 a=rtpmap:97 speex/16000 m=audio 8088 RTP/AVP 98 a=rtpmap:98 speex/8000 ``` #### Response Example N/A ``` -------------------------------- ### Speex SDP fmtp Parameters: Encoding Mode and Flexibility Source: https://github.com/xiph/speex/blob/master/doc/draft-ietf-avt-rtp-speex-01-tmp.txt Illustrates configuring the Speex encoding mode and allowing for flexible mode selection using SDP 'a=fmtp' directives. It shows setting a specific mode and also using 'any' for mode flexibility. ```sdp m=audio 8008 RTP/AVP 97 a=rtpmap:97 speex/8000 a=fmtp:97 mode=4 ``` ```sdp a=fmtp:97 mode=any;mode=1 ``` -------------------------------- ### Speex Intensity Stereo Decoding Example (C) Source: https://context7.com/xiph/speex/llms.txt Decodes stereo audio from an encoded mono stream using intensity stereo metadata. It initializes the decoder and stereo state, registers a callback for stereo requests, and then decodes and converts the mono stream to stereo. Requires the Speex library. ```c #include #include #include #include void stereo_decoding_example() { // Initialize decoder void *decoder = speex_decoder_init(&speex_wb_mode); SpeexBits bits; speex_bits_init(&bits); // Initialize stereo state SpeexStereoState *stereo_state = speex_stereo_state_init(); // Register stereo callback handler SpeexCallback callback; callback.callback_id = SPEEX_INBAND_STEREO; callback.func = speex_std_stereo_request_handler; callback.data = stereo_state; speex_decoder_ctl(decoder, SPEEX_SET_HANDLER, &callback); int frame_size; speex_decoder_ctl(decoder, SPEEX_GET_FRAME_SIZE, &frame_size); // Receive encoded data char encoded[200]; int encoded_size = 76; // Example // ... receive encoded data ... // Prepare stereo output buffer (interleaved) spx_int16_t stereo_output[640]; // frame_size * 2 channels // Load bits and decode speex_bits_read_from(&bits, encoded, encoded_size); // Decode to mono first speex_decode_int(decoder, &bits, stereo_output); // Convert mono to stereo using intensity stereo info speex_decode_stereo_int(stereo_output, frame_size, stereo_state); printf("Decoded stereo frame: %d samples per channel\n", frame_size); // stereo_output now contains interleaved L/R samples // ... send to audio output ... // Cleanup speex_stereo_state_destroy(stereo_state); speex_bits_destroy(&bits); speex_decoder_destroy(decoder); } ``` -------------------------------- ### Manage Speex Headers (C) Source: https://context7.com/xiph/speex/llms.txt Demonstrates the creation and parsing of Speex file format headers using the speex_header library. It covers initializing a header, setting various fields like sampling rate, channels, and bitrate, converting the header to a packet for transmission or storage, and parsing a received packet back into a header structure. This is essential for interoperability and stream identification. ```c #include #include void header_management_example() { // Initialize a Speex header SpeexHeader header; int sampling_rate = 16000; int channels = 1; speex_init_header(&header, sampling_rate, channels, &speex_wb_mode); // Set additional header fields header.vbr = 1; // VBR enabled header.frames_per_packet = 1; // One frame per packet header.bitrate = 24600; // Nominal bitrate // Get frame size from mode int frame_size; speex_mode_query(&speex_wb_mode, SPEEX_MODE_FRAME_SIZE, &frame_size); header.frame_size = frame_size; // Convert header to packet (for writing to file) int packet_size; char *header_packet = speex_header_to_packet(&header, &packet_size); if (header_packet != NULL) { printf("Header packet size: %d bytes\n", packet_size); printf("Speex version: %s\n", header.speex_version); printf("Mode: %d (0=NB, 1=WB, 2=UWB)\n", header.mode); printf("Sample rate: %d Hz\n", header.rate); printf("Channels: %d\n", header.nb_channels); printf("Frame size: %d samples\n", header.frame_size); // ... write header_packet to Ogg stream ... // Free the packet when done speex_header_free(header_packet); } // Parse header from packet (when reading file) char received_packet[80]; // ... read received_packet from Ogg stream ... memcpy(received_packet, header_packet, packet_size); // Simulate SpeexHeader *parsed_header = speex_packet_to_header(received_packet, packet_size); if (parsed_header != NULL) { printf("\nParsed header:\n"); printf(" Rate: %d Hz\n", parsed_header->rate); printf(" Mode ID: %d\n", parsed_header->mode); printf(" VBR: %d\n", parsed_header->vbr); printf(" Channels: %d\n", parsed_header->nb_channels); // Get the mode for decoder initialization const SpeexMode *mode = speex_lib_get_mode(parsed_header->mode); void *decoder = speex_decoder_init(mode); // ... use decoder ... speex_decoder_destroy(decoder); // Free parsed header speex_header_free(parsed_header); } } ``` -------------------------------- ### Configure Speex RTP Session Parameters with SDP fmtp Source: https://github.com/xiph/speex/blob/master/doc/draft-herlein-avt-rtp-speex-00.txt This snippet demonstrates how to use the a=fmtp directive in SDP to configure various parameters for a Speex RTP stream. It covers setting encoding mode, perceptual enhancement, variable bit rate, and comfort noise generation. Multiple parameters can be combined using a semicolon separator. ```sdp m=audio 8008 RTP/AVP 97 a=rtpmap:97 speex/8000 a=fmtp:97 mode=4 ``` ```sdp m=audio 8088 RTP/AVP 97 a=rtmap:97 speex/8000 a=fmtp:97 penh=1 ``` ```sdp a=fmtp:97 mode=any;penh=1 ``` ```sdp m=audio 8088 RTP/AVP 97 a=rtmap:97 speex/8000 a=fmtp:97 vbr=on;cng=on ``` -------------------------------- ### Speex SDP a=fmtp Parameters Source: https://github.com/xiph/speex/blob/master/doc/draft-herlein-avt-rtp-speex-00.txt This section describes the parameters that can be used with the `a=fmtp` directive in SDP to configure the Speex encoder on the remote end. ```APIDOC ## Speex SDP a=fmtp Parameters ### Description Configures the Speex encoder on the remote end using `a=fmtp` directive in SDP. These parameters can also be used in H.245 NonStandardMessage. ### Parameters #### Request Body (Implicit via a=fmtp) - **ptime** (integer) - Optional - Duration of each packet in milliseconds. Must be a multiple of 20. Defaults to 20. - **sr** (integer) - Optional - Actual sample rate in Hz. Defaults to 8000. - **ebw** (string) - Optional - Encoding bandwidth. Can be 'narrow', 'wide', or 'ultra'. Corresponds to 8000, 16000, and 32000 Hz sampling rates respectively. - **vbr** (string) - Optional - Variable bit rate. Can be 'on', 'off', or 'vad'. Defaults to 'off'. 'vad' uses constant bit rate with silence indicated by short frames. - **cng** (string) - Optional - Comfort noise generation. Can be 'on' or 'off'. Defaults to 'off'. - **mode** (integer) - Optional - Speex encoding mode. Can be {1,2,3,4,5,6,any}. Defaults to 3 (narrowband), 6 (wideband), or any (ultrawideband). - **penh** (integer) - Optional - Perceptual enhancement. 1 indicates recommended, 0 indicates not recommended. Defaults to 1. ### Request Example ``` a=fmtp:97 mode=4 ``` ### Response #### Success Response (200) - **status** (string) - Indicates successful configuration. #### Response Example ```json { "status": "Configuration applied successfully." } ``` ``` -------------------------------- ### Initialize and Decode Audio Frames with Speex C API Source: https://context7.com/xiph/speex/llms.txt Illustrates initializing a Speex decoder for narrowband mode, enabling perceptual enhancement, and decoding a compressed audio frame. It utilizes `speex_decoder_init`, `speex_decoder_ctl` for configuration, `speex_bits_read_from` to load data, and `speex_decode_int` for decoding. Includes handling for packet loss. ```c #include #include void decode_audio_example() { // Initialize decoder state for narrowband mode void *decoder_state = speex_decoder_init(&speex_nb_mode); if (decoder_state == NULL) { fprintf(stderr, "Failed to initialize decoder\n"); return; } // Initialize bit-unpacking structure SpeexBits bits; speex_bits_init(&bits); // Enable perceptual enhancement (improves quality) int enh = 1; speex_decoder_ctl(decoder_state, SPEEX_SET_ENH, &enh); // Get frame size int frame_size; speex_decoder_ctl(decoder_state, SPEEX_GET_FRAME_SIZE, &frame_size); // Prepare output buffer spx_int16_t output_frame[320]; // Assume we have encoded data char encoded_data[200]; int encoded_size = 38; // Example size // ... receive encoded_data from network/file ... // Load encoded data into bits speex_bits_read_from(&bits, encoded_data, encoded_size); // Decode the frame int ret = speex_decode_int(decoder_state, &bits, output_frame); if (ret == 0) { printf("Frame decoded successfully\n"); // ... use output_frame for playback ... } else if (ret == -1) { printf("End of stream\n"); } else if (ret == -2) { printf("Corrupt stream detected\n"); } // Packet loss handling - decode with NULL bits speex_bits_reset(&bits); ret = speex_decode_int(decoder_state, NULL, output_frame); printf("Decoded lost packet with concealment\n"); // Cleanup speex_bits_destroy(&bits); speex_decoder_destroy(decoder_state); } ``` -------------------------------- ### Querying Speex Library Version (C) Source: https://context7.com/xiph/speex/llms.txt Shows how to retrieve the Speex library version information at runtime. This includes obtaining the full version string and individual components (major, minor, micro) as well as any extra version details. ```c #include #include void version_info_example() { // Get version string const char *version_string; speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, &version_string); printf("Speex version: %s\n", version_string); // Get individual version components int major, minor, micro; speex_lib_ctl(SPEEX_LIB_GET_MAJOR_VERSION, &major); speex_lib_ctl(SPEEX_LIB_GET_MINOR_VERSION, &minor); speex_lib_ctl(SPEEX_LIB_GET_MICRO_VERSION, µ); printf("Version: %d.%d.%d\n", major, minor, micro); // Get extra version info const char *extra; speex_lib_ctl(SPEEX_LIB_GET_EXTRA_VERSION, &extra); if (extra && extra[0] != '\0') { printf("Extra version info: %s\n", extra); } } ```