aes67_convert.h 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /*
  2. * SPDX-FileCopyrightText: 2026 DatanoiseTV
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /*
  7. * Audio sample format conversion routines.
  8. *
  9. * Based on RAVENNA MTConvert pattern. Handles conversion between native
  10. * (little-endian, 32-bit left-justified) audio buffers and network
  11. * (big-endian, packed) RTP payload formats.
  12. *
  13. * Function pointer types allow per-stream codec dispatch without
  14. * branching in the hot path.
  15. */
  16. #pragma once
  17. #include <stdint.h>
  18. #include <stddef.h>
  19. #ifdef __cplusplus
  20. extern "C" {
  21. #endif
  22. /* --- Function pointer types (MTConvert pattern) --- */
  23. /* Convert interleaved int32 native samples to packed big-endian wire format.
  24. * Called once per TX packet. Set at stream creation based on codec. */
  25. typedef void (*aes67_convert_to_net_fn)(const int32_t *src, uint8_t *dst,
  26. uint32_t frame_count, uint8_t channels);
  27. /* Convert packed big-endian wire format to interleaved int32 native samples.
  28. * Called once per RX packet. Set at stream creation based on codec. */
  29. typedef void (*aes67_convert_from_net_fn)(const uint8_t *src, int32_t *dst,
  30. uint32_t frame_count, uint8_t channels);
  31. /* Resolve the appropriate conversion functions for a given codec/word_length */
  32. aes67_convert_to_net_fn aes67_get_to_net_fn(uint8_t word_length);
  33. aes67_convert_from_net_fn aes67_get_from_net_fn(uint8_t word_length);
  34. /* --- Per-codec conversion functions --- */
  35. /* L16: 16-bit linear PCM (2 bytes/sample on wire) */
  36. void aes67_convert_to_l16(const int32_t *src, uint8_t *dst,
  37. uint32_t frame_count, uint8_t channels);
  38. void aes67_convert_from_l16(const uint8_t *src, int32_t *dst,
  39. uint32_t frame_count, uint8_t channels);
  40. /* L24: 24-bit linear PCM (3 bytes/sample on wire) */
  41. void aes67_convert_to_l24(const int32_t *src, uint8_t *dst,
  42. uint32_t frame_count, uint8_t channels);
  43. void aes67_convert_from_l24(const uint8_t *src, int32_t *dst,
  44. uint32_t frame_count, uint8_t channels);
  45. /* L32: 32-bit linear PCM (4 bytes/sample on wire) */
  46. void aes67_convert_to_l32(const int32_t *src, uint8_t *dst,
  47. uint32_t frame_count, uint8_t channels);
  48. void aes67_convert_from_l32(const uint8_t *src, int32_t *dst,
  49. uint32_t frame_count, uint8_t channels);
  50. /* AM824: IEC 61937 encapsulated in 4-byte words.
  51. * Same wire format as L32 but with channel status and validity bits
  52. * in the lower 8 bits. For basic PCM passthrough, the conversion is
  53. * identical to L32. */
  54. void aes67_convert_to_am824(const int32_t *src, uint8_t *dst,
  55. uint32_t frame_count, uint8_t channels);
  56. void aes67_convert_from_am824(const uint8_t *src, int32_t *dst,
  57. uint32_t frame_count, uint8_t channels);
  58. /* Generic dispatch (uses switch internally -- prefer function pointers
  59. * in hot paths for zero-branch overhead) */
  60. void aes67_convert_to_net(const int32_t *src, uint8_t *dst,
  61. uint32_t frame_count, uint8_t channels,
  62. uint8_t word_length);
  63. void aes67_convert_from_net(const uint8_t *src, int32_t *dst,
  64. uint32_t frame_count, uint8_t channels,
  65. uint8_t word_length);
  66. #ifdef __cplusplus
  67. }
  68. #endif