encode.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /*
  2. * encode.c
  3. *
  4. * Copyright (C) 2023 bzt
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. *
  20. * @brief Binary to audio converter
  21. *
  22. */
  23. #include <stdint.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <math.h>
  28. #include "wav.h"
  29. #ifndef M_PI
  30. #define M_PI 3.14159265358979323846
  31. #endif
  32. extern int verbose;
  33. /* mp3 encoder */
  34. #include "libmp3lame/lame.h"
  35. /**
  36. * Encode binary into audio
  37. */
  38. uint8_t *encode(uint8_t *data, size_t size, int fmt, int en, int nb, int sy, int fm, int ng, int length, int hdr,
  39. int rate, int ol, int zl, int bitrate, int quality, size_t *outlen)
  40. {
  41. lame_t gf;
  42. uint8_t *out, *ptr, *buf = NULL;
  43. size_t sofar;
  44. int16_t *intbuf;
  45. int i, j, k, l, m, b, set, stop, len, in_limit, ret;
  46. uint64_t ulen, glen, us;
  47. wav_header_t *wav;
  48. *outlen = 0;
  49. /* check arguments */
  50. if(length < 1) length = 1;
  51. if(length > 4096) length = 4096;
  52. if(ng < 0) ng = 0;
  53. if(ng > 4096) ng = 4096;
  54. if(rate < 22050) rate = 22050;
  55. if(rate > 48000) rate = 48000;
  56. if(ol > 127) ol = 127;
  57. if(ol < -128) ol = -128;
  58. if(zl > 127) zl = 127;
  59. if(zl < -128) zl = -128;
  60. if(bitrate < 96) bitrate = 96;
  61. if(bitrate > 256) bitrate = 256;
  62. if(quality < 0) quality = 0;
  63. if(quality > 9) quality = 9;
  64. /* convert lengths in usec to samples */
  65. ulen = length; length = (uint64_t)length * (uint64_t)rate / 1000000;
  66. glen = ng; ng = (uint64_t)ng * (uint64_t)rate / 1000000;
  67. if(ulen < 4000000 / rate) ulen = 4000000 / rate;
  68. if(length < 4) length = 4;
  69. if(length > 4096) length = 4096;
  70. if(ng < 0) ng = 0;
  71. if(ng > 4096) ng = 4096;
  72. if(verbose)
  73. printf("%s samples, freq %d, length %d usec, gap %d usec\n", fm ? "FM" : "AM", rate, (int)ulen, (int)glen);
  74. if(!fm) {
  75. /* amplitude modulation */
  76. /* calculate how many samples make up a bit */
  77. set = length / 4;
  78. if(set < 2) set = 2;
  79. stop = length - set;
  80. /* create wave from bits */
  81. j = (sy == 3 ? 3 : (sy ? 2 : 1)); l = nb * j;
  82. len = (uint64_t)size * ((uint64_t)l * ulen + glen) * (uint64_t)rate / 1000000;
  83. if(verbose) {
  84. printf("number of bits %d, 1 bit %d samples (%d data %d stop, %d with %d%d sync), %d %s endian bits per byte, gap %d samples (total %d samples)\n",
  85. (int)(size * nb), length + ng, set, stop, length * j, sy & 1, sy & 2 ? 1 : 0, nb, en ? "little" : "big", ng, len);
  86. printf("sample rate %d, one level %d, zero level %d, hdr %d, fmt %d, bitrate %d, quality %d\n", rate, ol, zl, hdr, fmt, bitrate, quality);
  87. }
  88. out = (uint8_t*)malloc(sizeof(wav_header_t) + len + 8 * length);
  89. if(!out) return NULL;
  90. memset(out, zl, sizeof(wav_header_t) + len + 8 * length);
  91. ptr = out + sizeof(wav_header_t);
  92. /* start at length because we add a leader */
  93. for(i = 0, us = 4 * ulen; i < size; i++) {
  94. if(i && verbose > 1) printf("--------\n");
  95. for(j = 0; j < nb; j++) {
  96. /* recalculate sample position to counteract rounding errors */
  97. l = us * rate / 1000000;
  98. if(sy & 1) { memset(ptr + l, ol, set); l += length; us += ulen; }
  99. b = j < 8 && data[i] & (1 << (en ? j : (nb - 1) - j)) ? 1 : 0;
  100. if(verbose > 1) printf(" pos %8d byte %8d bit %d\n", (int)l, (int)i, b);
  101. if(b) memset(ptr + l, ol, set);
  102. l += length; us += ulen;
  103. if(sy & 2) { memset(ptr + l, hdr && !i && j < 7 ? zl : ol, set); l += length; us += ulen; }
  104. }
  105. if(ng) { memset(ptr + l, zl, ng); l += ng; us += glen; }
  106. }
  107. /* get actual length, add trailer */
  108. len = l + 4 * length;
  109. } else {
  110. /* frequency modulation */
  111. if(length < 8) length = 8;
  112. if(ng < 1) ng = length * 3 / 4;
  113. if(ng < 2) ng = 2;
  114. if((ol >= 0 && zl >= 0) || (ol < 0 && zl < 0)) zl = -ol;
  115. len = size * nb * (length + ng);
  116. if(verbose) {
  117. printf("number of bits %d, 1 bit %d - %d samples, %d %s endian bits per byte (max %d samples)\n",
  118. (int)(size * nb), length, length + ng, nb, en ? "little" : "big", len);
  119. printf("sample rate %d, fm %d, one level %d, zero level %d, fmt %d, bitrate %d, quality %d\n", rate, fm, ol, zl, fmt, bitrate, quality);
  120. }
  121. out = (uint8_t*)malloc(sizeof(wav_header_t) + len + length);
  122. if(!out) return NULL;
  123. memset(out, 0, sizeof(wav_header_t) + len + length);
  124. ptr = out + sizeof(wav_header_t);
  125. /* leader */
  126. m = fm == 1 ? ol : zl;
  127. for(k = 0, set = length / 2; k < set; k++)
  128. ptr[k] = m * sinf(M_PI*(float)(k+set)/(float)length) / 4;
  129. /* bits, either length or length+ng long */
  130. for(i = 0, m = ol, l = length / 2; i < size; i++) {
  131. if(i && verbose > 1) printf("--------\n");
  132. for(j = 0; j < nb; j++, l += b) {
  133. b = length + (j < 8 && data[i] & (1 << (en ? j : (nb - 1) - j)) ? ng : 0);
  134. if(verbose > 1) printf(" pos %8d byte %8d bit %d\n", (int)l, (int)i, b > length ? 1 : 0);
  135. set = b / 2; stop = b - set;
  136. switch(fm) {
  137. case 1:
  138. for(k = 0; k < set; k++)
  139. ptr[l + k] = zl * sinf(M_PI*(float)k/(float)set);
  140. for(k = 0; k < stop; k++)
  141. ptr[l + set + k] = ol * sinf(M_PI*(float)k/(float)stop);
  142. break;
  143. case 2:
  144. for(k = 0; k < set; k++)
  145. ptr[l + k] = ol * sinf(M_PI*(float)k/(float)set);
  146. for(k = 0; k < stop; k++)
  147. ptr[l + set + k] = zl * sinf(M_PI*(float)k/(float)stop);
  148. break;
  149. default:
  150. for(k = 0; k < b; k++)
  151. ptr[l + k] = m * sinf(M_PI*(float)k/(float)b);
  152. m = (m == ol ? zl : ol);
  153. break;
  154. }
  155. }
  156. }
  157. /* trailer */
  158. if(fm < 3) m = fm == 1 ? zl : ol;
  159. for(k = 0, set = length / 2; k < set; k++)
  160. ptr[l + k] = m * sinf(M_PI*(float)k/(float)length) / 4;
  161. /* get actual length */
  162. len = l + length / 2;
  163. }
  164. /* do we need mp3 compression? */
  165. if(fmt) {
  166. if(!(gf = lame_init())) { if(verbose) printf("lame init error\n"); free(out); return NULL; }
  167. lame_set_write_id3tag_automatic(gf, 0);
  168. lame_set_num_channels(gf, 1);
  169. lame_set_mode(gf, MONO);
  170. lame_set_num_samples(gf, len);
  171. lame_set_in_samplerate(gf, rate);
  172. lame_set_out_samplerate(gf, rate);
  173. lame_set_quality(gf, quality);
  174. lame_set_brate(gf, bitrate);
  175. if(lame_init_params(gf) < 0) { free(out); return NULL; }
  176. l = 0;
  177. in_limit = lame_get_maximum_number_of_samples(gf, LAME_MAXMP3BUFFER);
  178. if(in_limit < 1) in_limit = 1;
  179. if(verbose) printf("encoding mp3 with lame, in_limit %d bufmax %d\n", in_limit, LAME_MAXMP3BUFFER);
  180. intbuf = (int16_t*)malloc(in_limit * sizeof(int16_t));
  181. if(!intbuf) { free(out); return NULL; }
  182. for(sofar = 0; len > 0;) {
  183. l = len > in_limit ? in_limit : len;
  184. buf = (uint8_t*)realloc(buf, sofar + LAME_MAXMP3BUFFER);
  185. if(!buf) { free(intbuf); free(out); return NULL; }
  186. for(j = 0; j < l; j++) intbuf[j] = ptr[j] * 256;
  187. ret = lame_encode_buffer(gf, intbuf, NULL, l, buf + sofar, LAME_MAXMP3BUFFER);
  188. if(ret <= 0) break; else sofar += ret;
  189. ptr += l; len -= l;
  190. }
  191. buf = (uint8_t*)realloc(buf, sofar + LAME_MAXMP3BUFFER);
  192. if(!buf) { free(intbuf); free(out); return NULL; }
  193. ret = lame_encode_flush(gf, buf + sofar, LAME_MAXMP3BUFFER);
  194. if(ret > 0) sofar += ret;
  195. buf = (uint8_t*)realloc(buf, sofar + LAME_MAXMP3BUFFER);
  196. if(!buf) { free(intbuf); free(out); return NULL; }
  197. ret = lame_get_lametag_frame(gf, buf + sofar, LAME_MAXMP3BUFFER);
  198. if(ret > 0) memcpy(buf, buf + sofar, ret);
  199. free(intbuf);
  200. free(out);
  201. *outlen = sofar;
  202. out = buf;
  203. } else {
  204. /* no mp3, just return wave */
  205. wav = (wav_header_t*)out;
  206. memcpy(&wav->str_riff, "RIFF", 4);
  207. wav->wav_size = sizeof(wav_header_t) + len;
  208. memcpy(&wav->str_wave, "WAVEfmt ", 8);
  209. wav->fmt_chunk_size = 16;
  210. wav->audio_format = wav->channels = wav->frame_size = 1;
  211. wav->sample_rate = wav->byte_rate = rate;
  212. wav->bit_depth = 8;
  213. memcpy(&wav->str_data, "data", 4);
  214. wav->data_bytes = len;
  215. for(i = 0; i < len; i++) ptr[i] += 128;
  216. *outlen = wav->wav_size;
  217. }
  218. if(verbose) printf("returning audiofile %d bytes\n", (int)*outlen);
  219. return out;
  220. }
  221. /**
  222. * WASM helper
  223. */
  224. int doencode(uint8_t *data, size_t size, int fmt, int en, int nb, int sy, int fm, int ng, int length, int hdr,
  225. int rate, int ol, int zl, int bitrate, int quality, uint8_t *out, int outmax)
  226. {
  227. size_t outlen = 0;
  228. uint8_t *buf;
  229. verbose = 1;
  230. printf("-------- encode --------\n");
  231. buf = encode(data, size, fmt, en, nb, sy, fm, ng, length, hdr, rate, ol, zl, bitrate, quality, &outlen);
  232. if(outlen > (size_t)outmax) outlen = outmax;
  233. if(buf && outlen > 0) { memcpy(out, buf, outlen); free(buf); }
  234. return outlen;
  235. }