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.