hal-audio-sbc.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. // SPDX-License-Identifier: Apache-2.0
  2. /*
  3. * Copyright (C) 2013 Intel Corporation
  4. *
  5. */
  6. #define _GNU_SOURCE
  7. #include <stdbool.h>
  8. #include <string.h>
  9. #include <malloc.h>
  10. #include <stdlib.h>
  11. #include <sbc/sbc.h>
  12. #include "audio-msg.h"
  13. #include "hal-audio.h"
  14. #include "hal-log.h"
  15. #include "../profiles/audio/a2dp-codecs.h"
  16. #define MAX_FRAMES_IN_PAYLOAD 15
  17. #define SBC_QUALITY_MIN_BITPOOL 33
  18. #define SBC_QUALITY_STEP 5
  19. #if __BYTE_ORDER == __LITTLE_ENDIAN
  20. struct rtp_payload {
  21. unsigned frame_count:4;
  22. unsigned rfa0:1;
  23. unsigned is_last_fragment:1;
  24. unsigned is_first_fragment:1;
  25. unsigned is_fragmented:1;
  26. } __attribute__ ((packed));
  27. #elif __BYTE_ORDER == __BIG_ENDIAN
  28. struct rtp_payload {
  29. unsigned is_fragmented:1;
  30. unsigned is_first_fragment:1;
  31. unsigned is_last_fragment:1;
  32. unsigned rfa0:1;
  33. unsigned frame_count:4;
  34. } __attribute__ ((packed));
  35. #else
  36. #error "Unknown byte order"
  37. #endif
  38. struct media_packet_sbc {
  39. struct media_packet_rtp hdr;
  40. struct rtp_payload payload;
  41. uint8_t data[0];
  42. };
  43. struct sbc_data {
  44. a2dp_sbc_t sbc;
  45. sbc_t enc;
  46. uint16_t payload_len;
  47. size_t in_frame_len;
  48. size_t in_buf_size;
  49. size_t out_frame_len;
  50. unsigned frame_duration;
  51. unsigned frames_per_packet;
  52. };
  53. static const a2dp_sbc_t sbc_presets[] = {
  54. {
  55. .frequency = SBC_SAMPLING_FREQ_44100 | SBC_SAMPLING_FREQ_48000,
  56. .channel_mode = SBC_CHANNEL_MODE_MONO |
  57. SBC_CHANNEL_MODE_DUAL_CHANNEL |
  58. SBC_CHANNEL_MODE_STEREO |
  59. SBC_CHANNEL_MODE_JOINT_STEREO,
  60. .subbands = SBC_SUBBANDS_4 | SBC_SUBBANDS_8,
  61. .allocation_method = SBC_ALLOCATION_SNR |
  62. SBC_ALLOCATION_LOUDNESS,
  63. .block_length = SBC_BLOCK_LENGTH_4 | SBC_BLOCK_LENGTH_8 |
  64. SBC_BLOCK_LENGTH_12 | SBC_BLOCK_LENGTH_16,
  65. .min_bitpool = SBC_MIN_BITPOOL,
  66. .max_bitpool = SBC_BITPOOL_HQ_JOINT_STEREO_44100,
  67. },
  68. {
  69. .frequency = SBC_SAMPLING_FREQ_44100,
  70. .channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO,
  71. .subbands = SBC_SUBBANDS_8,
  72. .allocation_method = SBC_ALLOCATION_LOUDNESS,
  73. .block_length = SBC_BLOCK_LENGTH_16,
  74. .min_bitpool = SBC_MIN_BITPOOL,
  75. .max_bitpool = SBC_BITPOOL_HQ_JOINT_STEREO_44100,
  76. },
  77. {
  78. .frequency = SBC_SAMPLING_FREQ_48000,
  79. .channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO,
  80. .subbands = SBC_SUBBANDS_8,
  81. .allocation_method = SBC_ALLOCATION_LOUDNESS,
  82. .block_length = SBC_BLOCK_LENGTH_16,
  83. .min_bitpool = SBC_MIN_BITPOOL,
  84. .max_bitpool = SBC_BITPOOL_HQ_JOINT_STEREO_48000,
  85. },
  86. };
  87. static int sbc_get_presets(struct audio_preset *preset, size_t *len)
  88. {
  89. int i;
  90. int count;
  91. size_t new_len = 0;
  92. uint8_t *ptr = (uint8_t *) preset;
  93. size_t preset_size = sizeof(*preset) + sizeof(a2dp_sbc_t);
  94. count = sizeof(sbc_presets) / sizeof(sbc_presets[0]);
  95. for (i = 0; i < count; i++) {
  96. preset = (struct audio_preset *) ptr;
  97. if (new_len + preset_size > *len)
  98. break;
  99. preset->len = sizeof(a2dp_sbc_t);
  100. memcpy(preset->data, &sbc_presets[i], preset->len);
  101. new_len += preset_size;
  102. ptr += preset_size;
  103. }
  104. *len = new_len;
  105. return i;
  106. }
  107. static int sbc_freq2int(uint8_t freq)
  108. {
  109. switch (freq) {
  110. case SBC_SAMPLING_FREQ_16000:
  111. return 16000;
  112. case SBC_SAMPLING_FREQ_32000:
  113. return 32000;
  114. case SBC_SAMPLING_FREQ_44100:
  115. return 44100;
  116. case SBC_SAMPLING_FREQ_48000:
  117. return 48000;
  118. default:
  119. return 0;
  120. }
  121. }
  122. static const char *sbc_mode2str(uint8_t mode)
  123. {
  124. switch (mode) {
  125. case SBC_CHANNEL_MODE_MONO:
  126. return "Mono";
  127. case SBC_CHANNEL_MODE_DUAL_CHANNEL:
  128. return "DualChannel";
  129. case SBC_CHANNEL_MODE_STEREO:
  130. return "Stereo";
  131. case SBC_CHANNEL_MODE_JOINT_STEREO:
  132. return "JointStereo";
  133. default:
  134. return "(unknown)";
  135. }
  136. }
  137. static int sbc_blocks2int(uint8_t blocks)
  138. {
  139. switch (blocks) {
  140. case SBC_BLOCK_LENGTH_4:
  141. return 4;
  142. case SBC_BLOCK_LENGTH_8:
  143. return 8;
  144. case SBC_BLOCK_LENGTH_12:
  145. return 12;
  146. case SBC_BLOCK_LENGTH_16:
  147. return 16;
  148. default:
  149. return 0;
  150. }
  151. }
  152. static int sbc_subbands2int(uint8_t subbands)
  153. {
  154. switch (subbands) {
  155. case SBC_SUBBANDS_4:
  156. return 4;
  157. case SBC_SUBBANDS_8:
  158. return 8;
  159. default:
  160. return 0;
  161. }
  162. }
  163. static const char *sbc_allocation2str(uint8_t allocation)
  164. {
  165. switch (allocation) {
  166. case SBC_ALLOCATION_SNR:
  167. return "SNR";
  168. case SBC_ALLOCATION_LOUDNESS:
  169. return "Loudness";
  170. default:
  171. return "(unknown)";
  172. }
  173. }
  174. static void sbc_init_encoder(struct sbc_data *sbc_data)
  175. {
  176. a2dp_sbc_t *in = &sbc_data->sbc;
  177. sbc_t *out = &sbc_data->enc;
  178. sbc_init_a2dp(out, 0L, in, sizeof(*in));
  179. out->endian = SBC_LE;
  180. out->bitpool = in->max_bitpool;
  181. DBG("frequency=%d channel_mode=%s block_length=%d subbands=%d allocation=%s bitpool=%d-%d",
  182. sbc_freq2int(in->frequency),
  183. sbc_mode2str(in->channel_mode),
  184. sbc_blocks2int(in->block_length),
  185. sbc_subbands2int(in->subbands),
  186. sbc_allocation2str(in->allocation_method),
  187. in->min_bitpool, in->max_bitpool);
  188. }
  189. static void sbc_codec_calculate(struct sbc_data *sbc_data)
  190. {
  191. size_t in_frame_len;
  192. size_t out_frame_len;
  193. size_t num_frames;
  194. in_frame_len = sbc_get_codesize(&sbc_data->enc);
  195. out_frame_len = sbc_get_frame_length(&sbc_data->enc);
  196. num_frames = sbc_data->payload_len / out_frame_len;
  197. if (num_frames > MAX_FRAMES_IN_PAYLOAD)
  198. num_frames = MAX_FRAMES_IN_PAYLOAD;
  199. sbc_data->in_frame_len = in_frame_len;
  200. sbc_data->in_buf_size = num_frames * in_frame_len;
  201. sbc_data->out_frame_len = out_frame_len;
  202. sbc_data->frame_duration = sbc_get_frame_duration(&sbc_data->enc);
  203. sbc_data->frames_per_packet = num_frames;
  204. DBG("in_frame_len=%zu out_frame_len=%zu frames_per_packet=%zu",
  205. in_frame_len, out_frame_len, num_frames);
  206. }
  207. static bool sbc_codec_init(struct audio_preset *preset, uint16_t payload_len,
  208. void **codec_data)
  209. {
  210. struct sbc_data *sbc_data;
  211. if (preset->len != sizeof(a2dp_sbc_t)) {
  212. error("SBC: preset size mismatch");
  213. return false;
  214. }
  215. sbc_data = calloc(sizeof(struct sbc_data), 1);
  216. if (!sbc_data)
  217. return false;
  218. memcpy(&sbc_data->sbc, preset->data, preset->len);
  219. sbc_init_encoder(sbc_data);
  220. sbc_data->payload_len = payload_len;
  221. sbc_codec_calculate(sbc_data);
  222. *codec_data = sbc_data;
  223. return true;
  224. }
  225. static bool sbc_cleanup(void *codec_data)
  226. {
  227. struct sbc_data *sbc_data = (struct sbc_data *) codec_data;
  228. sbc_finish(&sbc_data->enc);
  229. free(codec_data);
  230. return true;
  231. }
  232. static bool sbc_get_config(void *codec_data, struct audio_input_config *config)
  233. {
  234. struct sbc_data *sbc_data = (struct sbc_data *) codec_data;
  235. switch (sbc_data->sbc.frequency) {
  236. case SBC_SAMPLING_FREQ_16000:
  237. config->rate = 16000;
  238. break;
  239. case SBC_SAMPLING_FREQ_32000:
  240. config->rate = 32000;
  241. break;
  242. case SBC_SAMPLING_FREQ_44100:
  243. config->rate = 44100;
  244. break;
  245. case SBC_SAMPLING_FREQ_48000:
  246. config->rate = 48000;
  247. break;
  248. default:
  249. return false;
  250. }
  251. config->channels = sbc_data->sbc.channel_mode == SBC_CHANNEL_MODE_MONO ?
  252. AUDIO_CHANNEL_OUT_MONO :
  253. AUDIO_CHANNEL_OUT_STEREO;
  254. config->format = AUDIO_FORMAT_PCM_16_BIT;
  255. return true;
  256. }
  257. static size_t sbc_get_buffer_size(void *codec_data)
  258. {
  259. struct sbc_data *sbc_data = (struct sbc_data *) codec_data;
  260. return sbc_data->in_buf_size;
  261. }
  262. static size_t sbc_get_mediapacket_duration(void *codec_data)
  263. {
  264. struct sbc_data *sbc_data = (struct sbc_data *) codec_data;
  265. return sbc_data->frame_duration * sbc_data->frames_per_packet;
  266. }
  267. static ssize_t sbc_encode_mediapacket(void *codec_data, const uint8_t *buffer,
  268. size_t len, struct media_packet *mp,
  269. size_t mp_data_len, size_t *written)
  270. {
  271. struct sbc_data *sbc_data = (struct sbc_data *) codec_data;
  272. struct media_packet_sbc *mp_sbc = (struct media_packet_sbc *) mp;
  273. size_t consumed = 0;
  274. size_t encoded = 0;
  275. uint8_t frame_count = 0;
  276. mp_data_len -= sizeof(mp_sbc->payload);
  277. while (len - consumed >= sbc_data->in_frame_len &&
  278. mp_data_len - encoded >= sbc_data->out_frame_len &&
  279. frame_count < sbc_data->frames_per_packet) {
  280. ssize_t read;
  281. ssize_t written = 0;
  282. read = sbc_encode(&sbc_data->enc, buffer + consumed,
  283. sbc_data->in_frame_len, mp_sbc->data + encoded,
  284. mp_data_len - encoded, &written);
  285. if (read < 0) {
  286. error("SBC: failed to encode block at frame %d (%zd)",
  287. frame_count, read);
  288. break;
  289. }
  290. frame_count++;
  291. consumed += read;
  292. encoded += written;
  293. }
  294. *written = encoded + sizeof(mp_sbc->payload);
  295. mp_sbc->payload.frame_count = frame_count;
  296. return consumed;
  297. }
  298. static bool sbc_update_qos(void *codec_data, uint8_t op)
  299. {
  300. struct sbc_data *sbc_data = (struct sbc_data *) codec_data;
  301. uint8_t curr_bitpool = sbc_data->enc.bitpool;
  302. uint8_t new_bitpool = curr_bitpool;
  303. switch (op) {
  304. case QOS_POLICY_DEFAULT:
  305. new_bitpool = sbc_data->sbc.max_bitpool;
  306. break;
  307. case QOS_POLICY_DECREASE:
  308. if (curr_bitpool > SBC_QUALITY_MIN_BITPOOL) {
  309. new_bitpool = curr_bitpool - SBC_QUALITY_STEP;
  310. if (new_bitpool < SBC_QUALITY_MIN_BITPOOL)
  311. new_bitpool = SBC_QUALITY_MIN_BITPOOL;
  312. }
  313. break;
  314. }
  315. if (new_bitpool == curr_bitpool)
  316. return false;
  317. sbc_data->enc.bitpool = new_bitpool;
  318. sbc_codec_calculate(sbc_data);
  319. info("SBC: bitpool changed: %d -> %d", curr_bitpool, new_bitpool);
  320. return true;
  321. }
  322. static const struct audio_codec codec = {
  323. .type = A2DP_CODEC_SBC,
  324. .use_rtp = true,
  325. .get_presets = sbc_get_presets,
  326. .init = sbc_codec_init,
  327. .cleanup = sbc_cleanup,
  328. .get_config = sbc_get_config,
  329. .get_buffer_size = sbc_get_buffer_size,
  330. .get_mediapacket_duration = sbc_get_mediapacket_duration,
  331. .encode_mediapacket = sbc_encode_mediapacket,
  332. .update_qos = sbc_update_qos,
  333. };
  334. const struct audio_codec *codec_sbc(void)
  335. {
  336. return &codec;
  337. }