// Input samples assumed to be in the range -32768 to 32767. // // Outputs are 0/1 (intended for a 1-bit DAC). // // The output gain determines how the 0/1 are treated. An output // of 0 treated as the value "-out_gain", and an output of 1 is // treated as the value "+out_gain". By default, pass in 32767. // Smaller values may be useful if your input isn't "full scale" // input. // void sdm ( const short *i_samp, // input sample array unsigned char *o_samp, // output sample array int num_samp, // number of inputs to process int oversamp, // oversampling ratio int out_gain // output gain ) { int error = 0; int i, j, samp; for (i = 0; i < num_samp; i++) { samp = *i_samp++; for (j = 0; j < oversamp; j++) { if (samp > error) { *o_samp++ = 1; error += out_gain - samp; } else { *o_samp++ = 0; error += -out_gain - samp; } } } } #ifdef TEST #include #include // Test code: Generate 10 samples of a sinewave and plot an 8x // oversampled version alongside it. int main(void) { short i_samp[10]; unsigned char o_samp[80]; int i, j; double a; // Initialize the sine wave. for (a = 0., i = 0; i < 10; i++, a += 0.2 * M_PI) i_samp[i] = (short)( 32767. * sin(a) ); // Perform sigma delta modulation. sdm(i_samp, o_samp, 10, 8, 32767); // Crude ASCII plot of the sine wave, 33 rows tall for (i = 16; i >= -16; i--) { int hi = 2048*i, lo = hi - 2048; for (j = 0; j < 79; j++) { int samp = i_samp[j / 8]; int outc = i == 0 && j % 8 == 0 ? '|' : hi >= samp && samp > lo ? '*' : i == 0 && j % 8 != 0 ? '-' : ' '; putchar(outc); } putchar('\n'); } putchar('\n'); putchar('\n'); // Crude ASCII plot of the sigma-delta modulated wave, 6 rows tall for (j = 0; j < 79; j++) putchar(o_samp[j] == 1 ? '-' : ' '); putchar('\n'); for (i = 0; i < 4; i++) { for (j = 0; j < 79; j++) putchar(o_samp[j] != o_samp[j+1] ? '|' : ' '); putchar('\n'); } for (j = 0; j < 79; j++) putchar(o_samp[j] == 0 ? '-' : ' '); putchar('\n'); return 0; } #endif