Altera_Forum
Honored Contributor
8 years agoCreating square waves of varying frequencies
Hi all,
I'm currently trying to produce sound via an Audio Controller by creating square waves that change in frequency depending on which switch on the FPGA is flipped. I'm able to get sound, but for some reason that I can not figure out all except for one note (A4 at 440Hz) are outputting the wrong tone. I've done some pretty extensive research and have come up dry as to what the problem is :( I'm dividing the Audio CODEC Chip Clock (clocked at 48kHz) for various Duty Cycles to produce the correct frequency. Here's a snippet of my code:
// Positive and negative amplitude parameters for square wave
parameter pos_amp = 32'h7FFFFFFF;
parameter neg_amp = 32'h80000000;
// Determines channel_audio_out via dac_out
wire signed channel_audio_out = dac_out ? pos_amp : neg_amp;
// Seperate 8-bit counter for each note
reg ac_counter_C4;
reg ac_counter_D4;
reg ac_counter_E4;
reg ac_counter_F4;
reg ac_counter_G4;
reg ac_counter_A4;
reg ac_counter_B4;
reg clear_audio_out_memory; // To clear audio_out buffer when no SW is flipped
reg write_audio_out; // To signal when to write to audio_out buffer
reg dac_out; // Determines pos_amp or neg_amp for channel_audio_out
// Determines dac_out via ac_counter's (AUD_XCK dividers)
always@(posedge AUD_XCK) // 48kHz
beginclear_audio_out_memory <= 1'b0;
if (SW == 1'b1) // C4 --- f = 261.626 Hz --- Duty Cycle = 184
begin
ac_counter_C4 <= ac_counter_C4 + 1'b1;
if (ac_counter_C4 >= 8'd183)
ac_counter_C4 <= 8'd0;
write_audio_out <= 1'b1;
if (ac_counter_C4 < 8'd92)
dac_out <= 1'b1;
else
dac_out <= 1'b0;
end
else if (SW == 1'b1) // D4 --- f = 293.665 Hz --- Duty Cycle = 164
begin
ac_counter_D4 <= ac_counter_D4 + 1'b1;
if (ac_counter_D4 >= 8'd163)
ac_counter_D4 <= 8'd0;
write_audio_out <= 1'b1;
if (ac_counter_D4 < 8'd82)
dac_out <= 1'b1;
else
dac_out <= 1'b0;
end
...etc for all notes...
else // NO SWITCH ON --- DEFAULT STATE
begin
ac_counter_C4 <= 1'd0;
ac_counter_D4 <= 1'd0;
ac_counter_E4 <= 1'd0;
ac_counter_F4 <= 1'd0;
ac_counter_G4 <= 1'd0;
ac_counter_A4 <= 1'd0;
ac_counter_B4 <= 1'd0;
write_audio_out <= 1'b0;
clear_audio_out_memory <= 1'b1;
dac_out <= 1'b0;
end
end
I'd also like to add that the fact that I have no reset is not a problem (that I'm aware), I have it in a different part of my code. If anyone could help me figure out where I went wrong it would be much appreciated, Thanks!