Jump to content

FPGA design: Noise - activated musical square waves


Michael Lee

1,076 views

I've tried a variety of FPGA "designs." The one I'm sharing now produces musical tones similar to the white keys on a piano for six octaves.

The tones are simple square waves which probably sound most like 8-bit video games from the 90's. The spacing of the tones use something called the just intonation temperament. Instead of powers of (1/12), just intonation uses simple fractions that are actually more in tune with each other. The downside of just intonation is that you can't easily change scales.

Each tone is activated when a noise source running at 50 million bits per second sends out by chance 26 1's in a row. It sounds pretty unlikely, but given the number of bits per second and the number of tones (N = 42), it happens enough to produce music. Here's a sample:

Here's what the spectrogram of this sample looks like. Square waves produce a fundamental sine wave and odd harmonics (3x, 5x, 7x, etc.)

spectro_16_26_36.thumb.png.ace800dc025ca6f1ed14ba7fd3f710cf.png

 The noise source is perhaps the most critical. In this particular project I'm using XOR'ed ring oscillators. These are described in the scientific literature. The big challenge is that no two ring oscillators are exactly alike. Despite having the same "length" of 101 delay gates, the idiosyncracies of chip transistors means the actual delay times will vary between each RO. Also, their susceptibility to noise will each be different. I can only hope that 16x RO's per tone is enough randomness to average out the variations so that each tone will trigger the same number of times. If you look carefully at the spectrogram, you will see certain tones are little more triggered than others.

Here are some voice samples after the signal is translated via machine learning:

"confident signal"

 

"it mirrors wonderful"

 

"given the opposite" 

 

"now that we're talking"

 

Finally, here's the Verilog code, for some future brave FPGA developer:

//
// Author: Michael S. Lee 
// Noise source-activate musical square wave tones
// Started: 12/2021
//
module XOR_loop_gate 
  #(parameter N = 149) // Length of each RO
  (input wire clki,
   output wire gate0);  
  wire [N:0] loop[M-1:0] /* synthesis keep */;
  reg [0:0] gate;
  reg [M-1:0] lpb;
  reg [L-1:0] buffer = 0;
  wire hit;
  reg [0:0] check; 
  integer ctr;
  parameter period = 65536 * 48; // duration of tone (in 50 Mhz samples)
  parameter M = 16; // # of ring oscillators
  parameter L = 26; // length of seq. of 1s to turn on gate
  genvar i, k;
  integer j;
  
  generate

  for (i = 0; i < M; i = i + 1)
   begin: loopnum
    assign loop[i][N] = ~ (loop[i][0]);
    for (k = 0; k < N; k = k + 1)
	 begin: loops
     assign loop[i][k] = loop[i][k+1]; 
    end
	end

  endgenerate
  
  assign hit = ^(lpb);
					  
  assign gate0 = gate;
  
  always @(posedge clki)
  begin
     for (j = 0 ; j < M; j = j + 1) begin
       lpb[j] <= loop[j][0];
	  end
	  buffer = (buffer << 1) + hit;
	  check = &(buffer);
	  if (check == 1) begin
	     ctr <= period;
		  gate <= 1;
	  end
	  else if (ctr > 0) begin
	     ctr <= ctr - 1;
	  end 
	  else begin
	     gate <= 0;
	  end
	  
  end  
endmodule

module Direct_Voice(clk,out);

  input clk;
  output wire out;
  parameter N = 42; // # of musical tones
  parameter bits = 7;
  reg [bits+1:0] PWM = 0;
  genvar k;
  integer i;
  wire [N-1:0] outw /* synthesis keep */;
  reg[N-1:0] outr;
  reg[18:0] outp[N];
  integer sum, suma[24];
  reg[22:0] clk2 = 0, clk3 = 0, clk5 = 0, 
            clk7 = 0, clk9 = 0, clk15 = 0;
  
  generate
    for (k = 0; k < N; k = k + 1)
	 begin: prep
		XOR_loop_gate #(101) test(clk, outw[k]);
    end
  endgenerate 
 
  assign out = PWM[bits+1];
  
  always @(posedge clk)
  begin
     
	  // Clocks for different musical tones
     clk2 = clk2 + 1;
	  clk3 = clk3 + 3;
	  clk5 = clk5 + 5;
	  clk7 = clk7 + 7;
	  clk9 = clk9 + 9;
	  clk15 = clk15 + 15;
	  
	  // Convert wire gates to registers
     for (i = 0 ; i < N; i = i + 1) begin
       outr[i] <= outw[i];
	  end
	  
     suma[0]  = (outr[0] & clk2[19])  + (outr[1] & clk3[19]);
	  suma[1]  = (outr[2] & clk5[20])  + (outr[3] & clk7[20]); 
	  suma[2]  = (outr[4] & clk9[21])  + (outr[5] & clk15[21]);
	  
     suma[3]  = (outr[6]  & clk2[18])  + (outr[7] & clk3[18]);
	  suma[4]  = (outr[8]  & clk5[19])  + (outr[9] & clk7[19]); 
	  suma[5]  = (outr[10] & clk9[20])  + (outr[11] & clk15[20]);

     suma[6]  = (outr[12] & clk2[17])  + (outr[13] & clk3[17]);
	  suma[7]  = (outr[14] & clk5[18])  + (outr[15] & clk7[18]); 
	  suma[8]  = (outr[16] & clk9[19])  + (outr[17] & clk15[19]);

     suma[9]  = (outr[18] & clk2[16])  + (outr[19] & clk3[16]);
	  suma[10] = (outr[20] & clk5[17])  + (outr[21] & clk7[17]); 
	  suma[11] = (outr[22] & clk9[18])  + (outr[23] & clk15[18]);

     suma[12] = (outr[24] & clk2[15])  + (outr[25] & clk3[15]);
	  suma[13] = (outr[26] & clk5[16])  + (outr[27] & clk7[16]); 
	  suma[14] = (outr[28] & clk9[17])  + (outr[29] & clk15[17]);

     suma[15] = (outr[30] & clk2[14])  + (outr[31] & clk3[14]);
	  suma[16] = (outr[32] & clk5[15])  + (outr[33] & clk7[15]); 
	  suma[17] = (outr[34] & clk9[16])  + (outr[35] & clk15[16]);
	  
	  suma[18] = (outr[36] & clk2[13])  + (outr[37] & clk3[13]);
	  suma[19] = (outr[38] & clk5[14])  + (outr[39] & clk7[14]); 
	  suma[20] = (outr[40] & clk9[15])  + (outr[41] & clk15[15]);
	  
	//  suma[21] = (outr[36] & clk2[20])  + (outr[37] & clk3[20]);
	//  suma[22] = (outr[38] & clk5[21])  + (outr[39] & clk7[21]); 
	//  suma[23] = (outr[40] & clk9[22])  + (outr[41] & clk15[22]);
	  
	  sum = 0;
     for (i = 0 ; i < 21; i = i + 1) begin
   	  sum = sum + suma[i];
	  end
	
     PWM = PWM[bits:0] + sum;
	  	  
  end
  
endmodule

 

14 Comments


Recommended Comments

These are impressing results Michael. If I got you right you each RO is made of 101 gates and you are combining 16 of these RO's for the controlling of one tone  by xoring them?

The voices are very clear. Are you using the same ML software you published in the community or is it trained solely to the signal of your musical tones?

Link to comment

Correct on the specifications. I'm using same "translator." I try to make my models as universal as possible and reuse the same ones for all of my experiments. My latest "musical tone" reverser uses as input the whole spectrogram, followed by sparsification (1 to 20 up to  1 to 80) and then reconstitutes the remaining "dots" as 60 ms tones. This provides a fast "tone-ification" of voice that I then train an ML model to reverse. This model can be used with either a tone-based signal (like the one in this thread) or a strong spectral subtraction of a noise signal.

For fun, this is the one legible phrase from my 1-minute recording this morning:

 

I hear "This is divine providence."

Link to comment
22 hours ago, Michael Lee said:

Two more quotes for today, using a different FPGA design, but same ML software.

 

"the transmitter"

 

"they clearly spin...circles"

 

 

 

I agree with Kevin. The results of your ML are very impressive in combination with your FPGA! Very well done Michael.

From what I remember the phython application you published and I installed does not contain ML. Could you publish the actual version with ML?

Link to comment
7 hours ago, Michael Lee said:

I do need to publish an ML version! It won't be plug & play like Spiricam, but it should be useable for the adventurous. 

It would be appreciated very much! I remember running one of your earlier version on my previous computer even without the NVIDIA graphics chipset.

Link to comment

Fantastic work Michael, have you tried to call someone in spirit to see if there is a response, this would go some way to verification with spirit?

Link to comment

I think it's all real. I mean I wouldn't being working so hard if I didn't think it was. Proof is hard, though. I've tried a little, like having a third party ask me to get information from my stream. But not enough - I hope others can help.

There's a few challenges. One is that you want messages to be clear enough such that two or more ppl can agree. Another challenge is for the messages to be long enough to be useful. A message like "remove the wire" isn't enough to make earth- shattering results. Third, I question the extent to which spirit knows all the answers. They might have solutions, but those might require tools or expertise I/we don't yet possess.

I feel like I maintain a connection both in ITC and mentally with Tesla. He seems to be the most avid researcher in this area There. Time will tell if it's an elaborate illusion or reality.

Link to comment

Consider the research and findings of Mark Macy and his INIT team in Luxemburg with the Fishbachs; where they were told by spirit communicators that in fact fairies and other mythical creatures truly existed, just not on this planet and time. Truly, what we might consider "illusions" or "myths", can and some are apparently reality elsewhere. 😉 

Link to comment

hi ya Michael very interesting stuff here,  I just wanted to point out something, I dont know if it occurred to you but that spectrogram  you posted above looks like a D.N.A. sequence, As soon as i see it  i thought WOW

Link to comment
Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.