Note: Synthesis, Harmonics (violin, piano, guitar, bass), frequencies, MIDI

I want to find how the notes were built. An example for an instrument (violin or piano), note LA4 (A4) has the main (or central) frequency FC at a frequency of 440 Hz with a specific amplitude AC, but it should also have other frequencies (harmonics?) FH with other amplitudes AH.

Harmonics have other frequencies that depend on the fundamental frequency with amplitudes (almost) less than the amplitude of the fundamental frequency.

Formation (creation) Notes

I want to know how notes are formed (set) (time is not considered).

Example: A4 = AC (FC) + AH1 (FH1) + AH2 (FH2) + AH3 (FH3) + AH4 (FH4) .... AHn (FHn) Perhaps FH1 = 2 * FC, FH2 = 3 * FC, FH3 = 4 * FC, etc ...

Comparison of instruments (violin and piano)

For piano, note LA4 (A4) has the main frequency FC at 440 Hz and Maybe FC (Piano) = FC (Violin), FH1 (Piano) = FH1 (Violin), FH2 (Piano) = FH2 (Violin) and etc ....

But, AC (Piano)! = AC (Violin), AH1 (Piano)! = AH1 (Violin), AH2 (Piano)! = AH2 (Violin), etc ...

An example of my question: http://www.phys.unsw.edu.au/jw/sound.spectrum.html

I want to reproduce these notes, avoiding the MIDI format, this can be implemented in Java / C # (or other programming in the language). Later, and more control over my sounds.

Thanks.

Ana

+6
source share
3 answers

I have it...

int iTone = 40; //Tone to be interpreted iSmplRate = 32000; //Sample Rate int NumBytesPerSample = 16; // 8 or 16 int NumChannels = 2; //1 Mono, 2 Stereo double Duration = 6.5; //Seconds performing Short sAmplit = 1200; int iNumSmpl = (int)(SampleRate*Duration); NumTotalBytes = (int)(SampleRate*Duration*NumBytesPerSample*NumChannels); ByteBuffer bbWav = ByteBuffer.allocate(NumTotalBytes); double dMaxInstr = (double)Short.MIN_VALUE; double dMinInstr = (double)Short.MAX_VALUE; //Amplitude for violin armonics double[] violAmps = {1.0, 0.286699025, 0.150079537, 0.042909002, 0.203797365, 0.229228698, 0.156931925, 0.115470898, 0.0, 0.097401803, 0.087653465, 0.052331036, 0.052922462, 0.038850593, 0.053554676, 0.053697434, 0.022270261, 0.013072562, 0.008585879, 0.005771505, 0.004343925, 0.002141371, 0.005343231, 0.000530244, 0.004711017, 0.009014153}; //Amplitude for piano armonics double[] pianAmps = {1.0, 0.399064778, 0.229404484, 0.151836061, 0.196754229, 0.093742264, 0.060871957, 0.138605419, 0.010535002, 0.071021868, 0.029954614, 0.051299684, 0.055948288, 0.066208224, 0.010067391, 0.00753679, 0.008196947, 0.012955577, 0.007316738, 0.006216476, 0.005116215, 0.006243983, 0.002860679, 0.002558108, 0.0, 0.001650392}; double[] operator = {1.0}; if (instrument.equals("violin")) { operator = violAmps; } if (instrument.equals("piano")) { operator = pianAmps; } double dFreq = 440.0*Math.pow(2.0, (iTone-69)/12.0; double dFreqRel = iSmplRate/dFreq; Integer iSampleInstrument = null; double PI2 = 2*Math.PI; int[] iSamplesInstr = new int[iNumSmpl]; for (int i = 0;i < iNumSmpl; i++) { Double Angle = i*PI2/dFreqRel; Double dInstrument = 0.0; for (int a = 1; a <=operator.length; a++) { dInstrument += operator[a-1]*Math.sin((double)a*Angle); } dMaxInstr = (dInstrument>dMaxInstr)?dInstrument:dMaxInstr; dMinInstr = (dInstrument<dMinInstr)?dInstrument:dMinInstr; iSampleInstrument = (int)(sAmplit*dInstrument); if (instrument.equals("violin")) { double FreqEnvV = iSmplRate/6.0; double FracEnvV = 35.0; double dEnvViolin = sAmplit*DStepperExt(Math.sin(1.0*i*PI2/FreqEnvV),4)/FracEnvV; iSampleInstrument = (int)(iSampleInstrument+dEnvViolin); } if (instrument.equals("piano")) { double FracEnvP = 8.0/10.0; double AngP = (double)i/(iSmplRate*FracEnvP); double EnvPiano = 1.0/Math.exp(AngP); iSampleInstrument = (int)(iSampleInstrument*EnvPiano); } dMxSmplInstr = (iSampleInstrument>dMxSmplInstr)?iSampleInstrument:dMxSmplInstr; dMnSmplInstr = (iSampleInstrument<dMnSmplInstr)?iSampleInstrument:dMnSmplInstr; iSamplesInstr[i] = iSampleInstrument; } double dMaxAbs = (Math.abs(dMaxInstr)>Math.abs(dMinInstr))?Math.abs(dMaxInstr):Math.abs(dMinInstr); double dMxAbsSmpl = (Math.abs(dMxSmplInstr)>Math.abs(dMnSmplInstr))?Math.abs(dMxSmplInstr):Math.abs(dMnSmplInstr); double dNormal = 1.0; if (dMxAbsSmpl > 32768.0) { dNormal = 32768.0/dMxAbsSmpl; } for (int i = 0;i < iNumSmpl; i++) { short sSampleInst = (short)(iSamplesInstr[i]*dNormal); try { if (iNumByteSmpl == 2) { bbWav.put((byte)((sSampleInst >> 0) & 0xFF)); bbWav.put((byte)((sSampleInst >> 8) & 0xFF)); if (iNumChnnls == 2) { bbWav.put((byte)((sSampleInst >> 0) & 0xFF)); bbWav.put((byte)((sSampleInst >> 8) & 0xFF)); } } else { byte ByteSample = (byte)((sSampleInst >> 8) & 0xFF); short ShrtSample = (short)(ByteSample & 0xFF); ShrtSample += 128; bbWav.put((byte)(ShrtSample & 0xFF)); if (iNumChnnls == 2) { bbWav.put((byte)(ShrtSample & 0xFF)); } } } catch (Exception e) { System.out.println(e.getMessage()); } 

This code is used in the violin tool:

  private Double DStepperExt(Double Val, Integer Steps) { //Return a value inside in range defined by step //Divide [-1.0,1.0]/(Steps-1), retorning the value according to the range //The value must be between 0.0 and 1.0 if (Steps <= 0.0) { return 0.0; } if (Val != -1.0 && Val != 1.0) { Val = Val - Val.intValue(); } Double sDouble = new Double(Steps-1); Double bdStep = 2.0/sDouble; Double bdRef = bdStep/2.0; bdRef = bdRef - 1.0; Double bdInit = -1.0; Double bdRet = null; for (int c = 0; c<=sDouble;c++) { if (Val < bdRef) { bdRet = bdInit; break; } else { bdInit = bdInit+bdStep; bdRef = bdRef+bdStep; } } return Math.min(bdRet.doubleValue(),1.0); } 

Try this code, my sound is not perfect, but very similar.

+3
source

Remember that what you are doing is a huge task. If your goal is to create your own synthesizer, which can sound like a piano, violin, etc., adding harmonics with certain amplitudes, then it is incredibly difficult to create a sound that is somehow realistic. The harmonics of an acoustic instrument change over time in a complex way. As explanatory notes, the attacks and delays of parts of the sound will be very different. If you try to measure the relative amplitudes of a real instrument at several points over time, and then synthesize sinusoids, the best thing you will achieve is something that will sound like a children's toy.

If this is what you want to do, you will need to analyze the spectrum over time of the sounds you want to emulate. The easiest way I suggest is to use something like Matlab, Octave or Scipy. If you want to visualize then try Sonic Visualiser or Marsyas.

If you want to create realistic playback, you have two options. One of them is to use Wavetable synthesis , namely how many cheap synthesizers (especially on PC sound cards) work. Another is to study Physical Modeling Synthesis , which mimics the physics of an instrument to create realistic sounds.

+2
source

If I understand correctly, you are trying to synthesize Fourier, hoping that something similar to the original tool. I see that the chances of success are pretty thin:

  • it will not work using midi, as this will require pure sine waves (which are not available with standard MIDI MIDI instruments).
  • you need a lot of data that is hard to find; note that your coefficients are not specific only to the โ€œpianoโ€, but also a step, so โ€œpiano a5โ€ has different meanings from โ€œpiano a6โ€,
    • this model assumes a steady state of tone (another goal is not achievable by the addition of sine waves); the characteristic of the device, however, is more determined by the phase of attack

I would recommend John Pierce "The Science of Musical Sound" for an introduction.

0
source

Source: https://habr.com/ru/post/916356/


All Articles