📄 wmwavegen.c
字号:
/*-----------------------------------------------------------------------------
* Copyright (c) Wolfson Microelectronics plc. All rights reserved.
*
* This software as well as any related documentation is furnished under
* license and may only be used or copied in accordance with the terms of the
* license. The information in this file is furnished for informational use
* only, is subject to change without notice, and should not be construed as
* a commitment by Wolfson Microelectronics plc. Wolfson Microelectronics plc
* assumes no responsibility or liability for any errors or inaccuracies that
* may appear in this document or any software that may be provided in
* association with this document.
*
* Except as permitted by such license, no part of this document may be
* reproduced, stored in a retrieval system, or transmitted in any form or by
* any means without the express written consent of Wolfson Microelectronics plc.
*
* $Id: WMWaveGen.c 2505 2005-11-30 17:30:38Z ian $
*
* Functions for generating different sound waveforms.
*
* Warning:
* This driver is specifically written for Wolfson Codecs. It is not a
* general CODEC device driver.
*
* -----------------------------------------------------------------------------*/
/*
* Include files
*/
#include <stdlib.h>
#include "WMCommon.h"
#include "WMWaveGen.h"
/*
* Global definitions
*/
typedef struct tagWaveTable
{
int nyquistDivisor;
const short *waveData;
} WaveTable;
#define AMPLITUDE_DIVISOR 32768
#if WM_TESTING
/*
* Function prototypes
*/
void private_GenerateWave(WM_AUDIO_STEREO_SAMPLE *buffer,
int nSamples,
int sampleRate,
unsigned short frequency,
unsigned short amplitude,
WM_WAVEGEN_FORMAT format,
WM_WAVEGEN_CTX *pRestart,
const WaveTable *waveTable
);
/*
* Wave tables for a square wave, synthesised using the following formula:
*
* y = sin(1*x)/1 + sin(3*x)/3 + sin (5*x)/5 + ...
*
* The tables give increasingly better approximations to the square wave
* by including more of the partials, however the higher order tables can
* only be used if Nyquist allows. The maximum frequency for the different
* tables at 44.1kHz is:
*
* Table frequency formula
* 1 22050Hz sample_rate/2
* 2 7350Hz sample_rate/6
* 3 4410Hz sample_rate/10
* 4 3150Hz sample_rate/14
* 5 2450Hz sample_rate/18
* 6 2004Hz sample_rate/22
* 7 1696Hz sample_rate/26
* 8 1470Hz sample_rate/30
* 9 1297Hz sample_rate/34
* 10 1160Hz sample_rate/38
*
*
* The samples have been scaled to all give -32767 to 32767 peak-to-peak
*/
/*
* 1st partial - i.e. just sine wave.
*
* y = sin(x)
*
* Nyquist divisor 2 => max frequency 22050Hz at 44.1kHz
* However, we will use this even if we're above the Nyquist limit
* because there isn't anything better.
*/
static const short SquareWave1[] =
{
0, 1608, 3212, 4808, 6393, 7962, 9512, 11039,
12539, 14010, 15446, 16846, 18204, 19519, 20787, 22005,
23170, 24279, 25329, 26319, 27245, 28105, 28898, 29621,
30273, 30852, 31356, 31785, 32137, 32412, 32609, 32728,
32767, 32728, 32609, 32412, 32137, 31785, 31356, 30852,
30273, 29621, 28898, 28105, 27245, 26319, 25329, 24279,
23170, 22005, 20787, 19519, 18204, 16846, 15446, 14010,
12539, 11039, 9512, 7962, 6393, 4808, 3212, 1608,
0, -1608, -3212, -4808, -6393, -7962, -9512, -11039,
-12539, -14010, -15446, -16846, -18204, -19519, -20787, -22005,
-23170, -24279, -25329, -26319, -27245, -28105, -28898, -29621,
-30273, -30852, -31356, -31785, -32137, -32412, -32609, -32728,
-32767, -32728, -32609, -32412, -32137, -31785, -31356, -30852,
-30273, -29621, -28898, -28105, -27245, -26319, -25329, -24279,
-23170, -22005, -20787, -19519, -18204, -16846, -15446, -14010,
-12539, -11039, -9512, -7962, -6393, -4808, -3212, -1608,
0
};
/*
* 2nd partial
*
* y = sin(x) + sin(3x)/3
*
* Nyquist divisor 6 => max frequency 7350Hz at 44.1kHz
*/
#if WM_SQUAREWAVE_PARTIAL2
static const short SquareWave2[] =
{
0, 3405, 6769, 10053, 13217, 16225, 19044, 21645,
24003, 26097, 27912, 29438, 30671, 31611, 32265, 32645,
32767, 32653, 32327, 31818, 31158, 30379, 29515, 28603,
27676, 26767, 25909, 25129, 24454, 23906, 23501, 23253,
23170, 23253, 23501, 23906, 24454, 25129, 25909, 26767,
27676, 28603, 29515, 30379, 31158, 31818, 32327, 32653,
32767, 32645, 32265, 31611, 30671, 29438, 27912, 26097,
24003, 21645, 19044, 16225, 13217, 10053, 6769, 3405,
0, -3405, -6769, -10053, -13217, -16225, -19044, -21645,
-24003, -26097, -27912, -29438, -30671, -31611, -32265, -32645,
-32767, -32653, -32327, -31818, -31158, -30379, -29515, -28603,
-27676, -26767, -25909, -25129, -24454, -23906, -23501, -23253,
-23170, -23253, -23501, -23906, -24454, -25129, -25909, -26767,
-27676, -28603, -29515, -30379, -31158, -31818, -32327, -32653,
-32767, -32645, -32265, -31611, -30671, -29438, -27912, -26097,
-24003, -21645, -19044, -16225, -13217, -10053, -6769, -3405,
0
};
#endif
/*
* 3rd partial
*
* y = sin(x) + sin(3x)/3 + sin(5x)/5
*
* Nyquist divisor 10 => max frequency 4410Hz at 44.1kHz
*/
#if WM_SQUAREWAVE_PARTIAL3
static const short SquareWave3[] =
{
0, 5150, 10157, 14883, 19205, 23020, 26247, 28835,
30760, 32029, 32678, 32767, 32379, 31614, 30580, 29391,
28158, 26984, 25958, 25149, 24608, 24360, 24408, 24731,
25291, 26031, 26883, 27773, 28628, 29376, 29958, 30326,
30452, 30326, 29958, 29376, 28628, 27773, 26883, 26031,
25291, 24731, 24408, 24360, 24608, 25149, 25958, 26984,
28158, 29391, 30580, 31614, 32379, 32767, 32678, 32029,
30760, 28835, 26247, 23020, 19205, 14883, 10157, 5150,
0, -5150, -10157, -14883, -19205, -23020, -26247, -28835,
-30760, -32029, -32678, -32767, -32379, -31614, -30580, -29391,
-28158, -26984, -25958, -25149, -24608, -24360, -24408, -24731,
-25291, -26031, -26883, -27773, -28628, -29376, -29958, -30326,
-30452, -30326, -29958, -29376, -28628, -27773, -26883, -26031,
-25291, -24731, -24408, -24360, -24608, -25149, -25958, -26984,
-28158, -29391, -30580, -31614, -32379, -32767, -32678, -32029,
-30760, -28835, -26247, -23020, -19205, -14883, -10157, -5150,
0
};
#endif
/*
* 4th partial
*
* y = sin(x) + sin(3x)/3 + sin(5x)/5 + sin(7x)/7
*
* Nyquist divisor 14 => max frequency 3150Hz at 44.1kHz
*/
#if WM_SQUAREWAVE_PARTIAL4
static const short SquareWave4[] =
{
0, 6859, 13376, 19239, 24192, 28059, 30755, 32291,
32767, 32361, 31303, 29856, 28280, 26816, 25652, 24919,
24674, 24904, 25533, 26439, 27469, 28467, 29289, 29824,
30008, 29829, 29326, 28585, 27722, 26866, 26146, 25668,
25500, 25668, 26146, 26866, 27722, 28585, 29326, 29829,
30008, 29824, 29289, 28467, 27469, 26439, 25533, 24904,
24674, 24919, 25652, 26816, 28280, 29856, 31303, 32361,
32767, 32291, 30755, 28059, 24192, 19239, 13376, 6859,
0, -6859, -13376, -19239, -24192, -28059, -30755, -32291,
-32767, -32361, -31303, -29856, -28280, -26816, -25652, -24919,
-24674, -24904, -25533, -26439, -27469, -28467, -29289, -29824,
-30008, -29829, -29326, -28585, -27722, -26866, -26146, -25668,
-25500, -25668, -26146, -26866, -27722, -28585, -29326, -29829,
-30008, -29824, -29289, -28467, -27469, -26439, -25533, -24904,
-24674, -24919, -25652, -26816, -28280, -29856, -31303, -32361,
-32767, -32291, -30755, -28059, -24192, -19239, -13376, -6859,
0
};
#endif
/*
* 5th partial
*
* y = sin(x) + sin(3x)/3 + sin(5x)/5 + sin(7x)/7 + sin(9x)/9
*
* Nyquist divisor 18 => max frequency 2450Hz at 44.1kHz
*/
#if WM_SQUAREWAVE_PARTIAL5
static const short SquareWave5[] =
{
0, 8577, 16486, 23154, 28174, 31363, 32767, 32649,
31429, 29611, 27698, 26116, 25154, 24930, 25398, 26372,
27582, 28736, 29579, 29948, 29795, 29190, 28296, 27334,
26526, 26051, 26006, 26388, 27096, 27959, 28776, 29355,
29565, 29355, 28776, 27959, 27096, 26388, 26006, 26051,
26526, 27334, 28296, 29190, 29795, 29948, 29579, 28736,
27582, 26372, 25398, 24930, 25154, 26116, 27698, 29611,
31429, 32649, 32767, 31363, 28174, 23154, 16486, 8577,
0, -8577, -16486, -23154, -28174, -31363, -32767, -32649,
-31429, -29611, -27698, -26116, -25154, -24930, -25398, -26372,
-27582, -28736, -29579, -29948, -29795, -29190, -28296, -27334,
-26526, -26051, -26006, -26388, -27096, -27959, -28776, -29355,
-29565, -29355, -28776, -27959, -27096, -26388, -26006, -26051,
-26526, -27334, -28296, -29190, -29795, -29948, -29579, -28736,
-27582, -26372, -25398, -24930, -25154, -26116, -27698, -29611,
-31429, -32649, -32767, -31363, -28174, -23154, -16486, -8577,
0
};
#endif
/*
* 6th partial
*
* y = sin(x) + sin(3x)/3 + sin(5x)/5 + sin(7x)/7 + sin(9x)/9 + sin(11x)/11
*
* Nyquist divisor 22 => max frequency 2004Hz at 44.1kHz
*/
#if WM_SQUAREWAVE_PARTIAL6
static const short SquareWave6[] =
{
0, 10240, 19342, 26392, 30877, 32767, 32479, 30758,
28479, 26449, 25231, 25053, 25804, 27115, 28503, 29520,
29884, 29543, 28669, 27587, 26661, 26181, 26276, 26885,
27782, 28661, 29235, 29323, 28909, 28142, 27282, 26617,
26368, 26617, 27282, 28142, 28909, 29323, 29235, 28661,
27782, 26885, 26276, 26181, 26661, 27587, 28669, 29543,
29884, 29520, 28503, 27115, 25804, 25053, 25231, 26449,
28479, 30758, 32479, 32767, 30877, 26392, 19342, 10240,
0, -10240, -19342, -26392, -30877, -32767, -32479, -30758,
-28479, -26449, -25231, -25053, -25804, -27115, -28503, -29520,
-29884, -29543, -28669, -27587, -26661, -26181, -26276, -26885,
-27782, -28661, -29235, -29323, -28909, -28142, -27282, -26617,
-26368, -26617, -27282, -28142, -28909, -29323, -29235, -28661,
-27782, -26885, -26276, -26181, -26661, -27587, -28669, -29543,
-29884, -29520, -28503, -27115, -25804, -25053, -25231, -26449,
-28479, -30758, -32479, -32767, -30877, -26392, -19342, -10240,
0
};
#endif
/*
* 7th partial
*
* y = sin(x) + sin(3x)/3 + sin(5x)/5 + sin(7x)/7 + sin(9x)/9 + sin(11x)/11
* + sin(13x)/13
*
* Nyquist divisor 26 => max frequency 1696Hz at 44.1kHz
*/
#if WM_SQUAREWAVE_PARTIAL7
static const short SquareWave7[] =
{
0, 11913, 22040, 29077, 32525, 32767, 30876, 28228,
26067, 25150, 25603, 26994, 28594, 29701, 29910, 29239,
28071, 26956, 26372, 26530, 27304, 28317, 29108, 29343,
28943, 28114, 27239, 26709, 26751, 27335, 28188, 28925,
29213, 28925, 28188, 27335, 26751, 26709, 27239, 28114,
28943, 29343, 29108, 28317, 27304, 26530, 26372, 26956,
28071, 29239, 29910, 29701, 28594, 26994, 25603, 25150,
26067, 28228, 30876, 32767, 32525, 29077, 22040, 11913,
0, -11913, -22040, -29077, -32525, -32767, -30876, -28228,
-26067, -25150, -25603, -26994, -28594, -29701, -29910, -29239,
-28071, -26956, -26372, -26530, -27304, -28317, -29108, -29343,
-28943, -28114, -27239, -26709, -26751, -27335, -28188, -28925,
-29213, -28925, -28188, -27335, -26751, -26709, -27239, -28114,
-28943, -29343, -29108, -28317, -27304, -26530, -26372, -26956,
-28071, -29239, -29910, -29701, -28594, -26994, -25603, -25150,
-26067, -28228, -30876, -32767, -32525, -29077, -22040, -11913,
0
};
#endif
/*
* 8th partial
*
* y = sin(x) + sin(3x)/3 + sin(5x)/5 + sin(7x)/7 + sin(9x)/9 + sin(11x)/11
* + sin(13x)/13 + sin(15x)/15
*
* Nyquist divisor 30 => max frequency 1470Hz at 44.1kHz
*/
#if WM_SQUAREWAVE_PARTIAL8
static const short SquareWave8[] =
{
0, 13416, 24238, 30775, 32767, 31336, 28414, 25909,
24991, 25776, 27510, 29100, 29712, 29156, 27888, 26690,
26217, 26660, 27691, 28683, 29081, 28700, 27803, 26928,
26572, 26918, 27741, 28551, 28884, 28556, 27769, 26985,
26662, 26985, 27769, 28556, 28884, 28551, 27741, 26918,
26572, 26928, 27803, 28700, 29081, 28683, 27691, 26660,
26217, 26690, 27888, 29156, 29712, 29100, 27510, 25776,
24991, 25909, 28414, 31336, 32767, 30775, 24238, 13416,
0, -13416, -24238, -30775, -32767, -31336, -28414, -25909,
-24991, -25776, -27510, -29100, -29712, -29156, -27888, -26690,
-26217, -26660, -27691, -28683, -29081, -28700, -27803, -26928,
-26572, -26918, -27741, -28551, -28884, -28556, -27769, -26985,
-26662, -26985, -27769, -28556, -28884, -28551, -27741, -26918,
-26572, -26928, -27803, -28700, -29081, -28683, -27691, -26660,
-26217, -26690, -27888, -29156, -29712, -29100, -27510, -25776,
-24991, -25909, -28414, -31336, -32767, -30775, -24238, -13416,
0,
};
#endif
/*
* 9th partial
*
* y = sin(x) + sin(3x)/3 + sin(5x)/5 + sin(7x)/7 + sin(9x)/9 + sin(11x)/11
* + sin(13x)/13 + sin(15x)/15 + sin(17x)/17
*
* Nyquist divisor 34 => max frequency 1297Hz at 44.1kHz
*/
#if WM_SQUAREWAVE_PARTIAL9
static const short SquareWave9[] =
{
0, 15144, 26637, 32415, 32767, 29923, 26756, 25334,
26110, 28081, 29712, 29976, 28915, 27439, 26610, 26921,
28034, 29097, 29374, 28734, 27695, 27017, 27159, 27974,
28851, 29159, 28699, 27827, 27181, 27223, 27910, 28737,
29101, 28737, 27910, 27223, 27181, 27827, 28699, 29159,
28851, 27974, 27159, 27017, 27695, 28734, 29374, 29097,
28034, 26921, 26610, 27439, 28915, 29976, 29712, 28081,
26110, 25334, 26756, 29923, 32767, 32415, 26637, 15144,
0, -15144, -26637, -32415, -32767, -29923, -26756, -25334,
-26110, -28081, -29712, -29976, -28915, -27439, -26610, -26921,
-28034, -29097, -29374, -28734, -27695, -27017, -27159, -27974,
-28851, -29159, -28699, -27827, -27181, -27223, -27910, -28737,
-29101, -28737, -27910, -27223, -27181, -27827, -28699, -29159,
-28851, -27974, -27159, -27017, -27695, -28734, -29374, -29097,
-28034, -26921, -26610, -27439, -28915, -29976, -29712, -28081,
-26110, -25334, -26756, -29923, -32767, -32415, -26637, -15144,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -