Square wave = sign(sinusoidal wave) So then why isn't the following code creating a square wave: Code: int sgn(double d){ if (d>=0) d=1; else d=-1; return d; } static void generate_square(const snd_pcm_channel_area_t *areas, snd_pcm_uframes_t offset, int count, double *_phase) { static double max_phase = 2. * M_PI; double phase = *_phase; double step = max_phase*freq/(double)rate; unsigned char *samples[channels]; int steps[channels]; unsigned int chn; int format_bits = snd_pcm_format_width(format); unsigned int maxval = (1 << (format_bits - 1)) - 1; int bps = format_bits / 8; // bytes per sample int phys_bps = snd_pcm_format_physical_width(format) / 8; int big_endian = snd_pcm_format_big_endian(format) == 1; int to_unsigned = snd_pcm_format_unsigned(format) == 1; int is_float = (format == SND_PCM_FORMAT_FLOAT_LE || format == SND_PCM_FORMAT_FLOAT_BE); double amplitude_scale = amplitude/8.56; // verify and prepare the contents of areas for (chn = 0; chn < channels; chn++) { if ((areas[chn].first % 8) != 0) { printf("areas[%i].first == %i, aborting...", chn , areas[chn].first); exit(EXIT_FAILURE); } samples[chn] = (((unsigned char *)areas[chn].addr) + (areas[chn].first / 8)); if ((areas[chn].step % 16) != 0) { // printf("areas[%i].step == %i, aborting... ", chn areas[chn].step); exit(EXIT_FAILURE); } steps[chn] = areas[chn].step / 8; samples[chn] += offset * steps[chn]; } // fill the channel areas while (count-- > 0) { union { float f; int i; } fval; int res, i; if (is_float) { int a = sgn(amplitude_scale * sin(phase) * maxval); fval.f = (float) a; res = fval.i; } else { int b = sgn(amplitude_scale * sin(phase) * maxval); res = b; } if (to_unsigned) res ^= 1U << (format_bits - 1); for (chn = 0; chn < channels; chn++) { // Generate data in native endian format if (big_endian) { for (i = 0; i < bps; i++) *(samples[chn] + phys_bps - 1 - i) = (res >> i * 8) & 0xff; } else { for (i = 0; i < bps; i++) *(samples[chn] + i) = (res >> i * 8) & 0xff; } samples[chn] += steps[chn]; } phase += step; if (phase >= max_phase) phase -= max_phase; } *_phase = phase; } If I take out the sgn function from the code, it generates a sine wave. Any help would be greatly appreciated.
hi i am studying electrical engineering. and i have not seen anything like this is in c.SORRY i cant help you but can you tell me how you did this and what you are doing. how do you do this in c? i might learn and try thanks.
Bit tricky as several variables that have a bearing are not defined (freq, rate, amplitude and probably others); you don't say what output you DO get or what output you get when you miss off the sgn (other than that it is a sine wave). At a guess you're probably running into C's fondness of converting everything to integers. Try casting maxval to a double and see what happens, i.e.: Code: int a = sgn(amplitude_scale * sin(phase) * (double)maxval); Does the sine wave that you get when you miss of sgn() vary from -amplitude_scale*maxval to +amplitude_scale*maxval or from 0 to some maximum? If so then you don't have a sine wave as such, you have sin()+offset, which would not convert to a square with a simple call to sgn(); you would have to subtract the offset, call sgn then add the offset back in. For more accurate analysis please upload a minimal program that is complete and that shows the output for the two test points pi/2 and 3pi/2 (i.e. the turning points, which will be +1 and -1 whether sgn is called or not).
Hi this is actually a sample c program that I got form the ALSA website. It is called pcm.c. It is for Linux based systems. I can't seem to post the link. So if you google pcm.c, it is the first result.
Solution: The sgn function should only be for the sin function int a = amplitude_scale * sgn(sin(phase)) * maxval;
Sorry I realised that I didn't explain fully what I was doing in my first reply to you. I am trying to build a gui that will output a sine and square wave with user inputs of frequency and amplitude. I am using the sample code form the alsa website called pcm.c which generates a sine wave. It is code for alsa on linux systems. I have built the gui and have integrated the sine wave and I am now trying to implement the square wave. Good luck in your learnings.