{"id":1220,"date":"2010-03-05T08:36:04","date_gmt":"2010-03-05T06:36:04","guid":{"rendered":"https:\/\/yehar.com\/blog\/?p=1220"},"modified":"2012-08-11T11:55:48","modified_gmt":"2012-08-11T08:55:48","slug":"multiplierless-sine-wave-look-up-table-generation","status":"publish","type":"post","link":"https:\/\/yehar.com\/blog\/?p=1220","title":{"rendered":"Sine wave look-up table generation"},"content":{"rendered":"<p>2010-03-05<\/p>\n<p>Here is a method for generating a sine look-up table in case you have little (a few kilobytes of) program memory. The idea goes like this: Let's say you have a sine wave lookup table of length 1024 with a 24-bit amplitude range. If you take the difference between successive samples, the range of the numbers is reduced. If you repeat the process a total of 3 times, the data will be dominated by the 3rd differential of the quantization noise and will have a range of -4 to 3, which can be conveniently stored in 3 bits only. This program below does the reverse, it generates the sine table from the 3-bit values, and also takes advantage of the symmetry properties of sine. So, instead of wasting 1024 program memory words for storing the original sine table, in the c-language implementation below, the compressed data takes only 35 24-bit words and the decompression code hopefully not too much more.<\/p>\n<pre>\/* Multiplierless 1024-sample, 24-bit sine table generator\r\n *\r\n * by Olli Niemitalo in 2010-03-07.\r\n * This work is placed in the public domain.\r\n *\/\r\n\r\n#include <stdio.h>;\r\n\r\n\/* Sine table with one extra sample to enable interpolation\r\n *\r\n * Sine with amplitude -0x800000 .. 0x800000 was rounded to\r\n * nearest integer and truncated to -0x800000 .. 0x7fffff.\r\n * int data type must be at least 24-bit.\r\n *\/\r\nint sineTable[1025];\r\n\r\nvoid generateTable() {\r\n  int i, j, k;\r\n  const int magic[33] = {\r\n    0x691864, 0x622299, 0x2CB61A, 0x461622,\r\n    0x62165A, 0x85965A, 0x0D3459, 0x65B10C,\r\n    0x50B2D2, 0x4622D9, 0x88C45B, 0x461828,\r\n    0x6616CC, 0x6CC2DA, 0x512543, 0x65B69A,\r\n    0x6D98CC, 0x4DB50B, 0x86350C, 0x7136A2,\r\n    0x6A974B, 0x6D531B, 0x70D514, 0x4EA714,\r\n    0x5156A4, 0x393A9D, 0x714A6C, 0x755555,\r\n    0x5246EB, 0x916556, 0x7245CD, 0xB4F3CE,\r\n    0x6DBC7A\r\n  };\r\n  k = 0;\r\n  for (i = 0; i < 33; i++) {\r\n    for (j = 0; j < 24; j += 3) {\r\n      sineTable[k++] = ((magic[i] >> j) & 7) - 4;\r\n    }\r\n  }\r\n  sineTable[1] = 51472;\r\n  for (i = 3; i > 0; i--) {\r\n    for (j = i; j <= 256; j++) {\r\n      k = sineTable[j - 1];\r\n      sineTable[j] = k + sineTable[j];\r\n      sineTable[513-j] = k;\r\n      sineTable[511+j] = -k;\r\n      sineTable[1025-j] = -k;\r\n    }\r\n  }\r\n  sineTable[768] = -0x800000;\r\n}\r\n\r\nint main() {\r\n  int i;\r\n\r\n  generateTable();\r\n\r\n  \/* Printout *\/\r\n  for (i = 0; i < 1025; i++) {\r\n    printf(\"%d\\t%d\\n\", i, sineTable[i]);\r\n  }\r\n\r\n  return 0;\r\n}<\/pre>\n<p>Here is a spreadsheet that illustrates the algorithm: <a href=\"http:\/\/yehar.com\/blog\/wp-content\/uploads\/2009\/09\/sinetable.xls\">sinetable.xls<\/a>. The above implementation additionally embeds the seeds 0 and -3 in the magic data<\/p>\n","protected":false},"excerpt":{"rendered":"<p>2010-03-05 Here is a method for generating a sine look-up table in case you have little (a few kilobytes of) program memory. The idea goes like this: Let&#8217;s say you have a sine wave lookup table of length 1024 with a 24-bit amplitude range. If you take the difference between successive samples, the range of &hellip; <a href=\"https:\/\/yehar.com\/blog\/?p=1220\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Sine wave look-up table generation&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":3570,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"_links":{"self":[{"href":"https:\/\/yehar.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1220"}],"collection":[{"href":"https:\/\/yehar.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/yehar.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/yehar.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/yehar.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1220"}],"version-history":[{"count":2,"href":"https:\/\/yehar.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1220\/revisions"}],"predecessor-version":[{"id":3493,"href":"https:\/\/yehar.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1220\/revisions\/3493"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/yehar.com\/blog\/index.php?rest_route=\/wp\/v2\/media\/3570"}],"wp:attachment":[{"href":"https:\/\/yehar.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1220"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/yehar.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1220"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/yehar.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1220"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}