private void textBoxNewFinal_TextChanged(object sender, EventArgs e) { recalcReentranceGuard++; try { if (recalcReentranceGuard == 1) { // reverse-engineer other parameters from this desired value double duration; Double.TryParse(textBoxDuration.Text, out duration); double initial, final; Double.TryParse(textBoxInitial.Text, out initial); Double.TryParse(textBoxFinal.Text, out final); double newEnd; Double.TryParse(textBoxEndOffset.Text, out newEnd); double newFinal; Double.TryParse(textBoxNewFinal.Text, out newFinal); bool exponential = comboBoxFunction.SelectedIndex != 0; if (!exponential) { // linear newEnd = (newFinal - initial) / (final - initial); } else { // exponential double initialDecibels = Synthesizer.ExpSegEndpointToLog(initial); double finalDecibels = Synthesizer.ExpSegEndpointToLog(final); double newFinalDecibels = Synthesizer.ExpSegEndpointToLog(newFinal); newEnd = (newFinalDecibels - initialDecibels) / (finalDecibels - initialDecibels); } textBoxEndOffset.Text = newEnd.ToString(); } } finally { recalcReentranceGuard--; } Recalculate(false /*updateInitialFinal*/); }
private double F(double x) // x normalized to [0..1] { if (!exponential) { return(initial + x * (final - initial)); } else { double logInitial = Synthesizer.ExpSegEndpointToLog(initial); double logFinal = Synthesizer.ExpSegEndpointToLog(final); double y = logInitial + x * (logFinal - logInitial); return(Synthesizer.ExpSegEndpointToLinear(y)); } }
public static void Completion( PlayFileWithEffectsGeneratorParams <T, W> generatorParams, ref ClipInfo clipInfo) { if (generatorParams.synthState != null) { Synthesizer.SynthStateRec.FinalizeSynthesizer( generatorParams.synthState, (generatorParams.result == Synthesizer.SynthErrorCodes.eSynthDone) && (generatorParams.exception == null) /*writeOutputLogs*/); generatorParams.synthState = null; } if (generatorParams.reader != null) { generatorParams.reader.Close(); generatorParams.reader = null; } if (generatorParams.stream != null) { generatorParams.stream.Close(); generatorParams.stream = null; } string interactionLogFinal = generatorParams.interactionLog.ToString(); if (interactionLogFinal.Length != 0) { IInteractionWindowService interaction = generatorParams.mainWindow.GetInteractionWindow(); interaction.Append(interactionLogFinal); } string message = null; if (generatorParams.exception != null) { message = generatorParams.exception.ToString(); } else if (generatorParams.result != Synthesizer.SynthErrorCodes.eSynthDone) { message = Synthesizer.GetErrorMessage(generatorParams.result, generatorParams.errorInfo); } if (message != null) { MessageBox.Show(message, "Synthesis Error", MessageBoxButtons.OK, MessageBoxIcon.Stop); } }
public static void SynthesizerMainLoop <U>( SynthesizerGeneratorParams <T, W> generatorParams, Synthesizer.DataOutCallbackMethod <OutputGeneric <T, U, W> > dataCallback, OutputGeneric <T, U, W> dataCallbackState, Synthesizer.StopTask stopper) { try { generatorParams.result = Synthesizer.DoSynthesizer( generatorParams.document, dataCallback, dataCallbackState, generatorParams.listOfTracks, generatorParams.keyTrack, generatorParams.frameToStartAt, generatorParams.samplingRate * generatorParams.oversamplingFactor, generatorParams.oversamplingFactor, generatorParams.envelopeRate, generatorParams.defaultBeatsPerMinute, generatorParams.overallVolumeScalingReciprocal, generatorParams.scanningGap, stopper, generatorParams.showSummary, out generatorParams.errorInfo, generatorParams.interactionLog, generatorParams.deterministic, generatorParams.randomSeed, generatorParams.automationSettings); } catch (Exception exception) { Program.WriteLog("SynthesizerMainLoop", exception.ToString()); generatorParams.exception = exception; stopper.Stop(); } finally { generatorParams.completed = true; } }
public static void SynthesizerCompletion( SynthesizerGeneratorParams <T, W> generatorParams, ref ClipInfo clipInfo) { string interactionLogFinal = generatorParams.interactionLog.ToString(); if (interactionLogFinal.Length != 0) { IInteractionWindowService interaction = generatorParams.mainWindow.GetInteractionWindow(); interaction.Append(interactionLogFinal); } string message = null; if (generatorParams.exception != null) { message = generatorParams.exception.ToString(); } else if (generatorParams.result != Synthesizer.SynthErrorCodes.eSynthDone) { message = Synthesizer.GetErrorMessage(generatorParams.result, generatorParams.errorInfo); } if (message != null) { MessageBox.Show(message, "Synthesis Error", MessageBoxButtons.OK, MessageBoxIcon.Stop); } if ((message == null) && generatorParams.clipWarn && (clipInfo.clippedSampleCount != 0)) { string clippingMessage = String.Format( "{0} out of {1} samples were clipped, with a maximum overextent of {2:0.000000}. Set the inverse volume to be greater than {3:0.000000} to eliminate the clipping.", clipInfo.clippedSampleCount, clipInfo.totalSampleCount, clipInfo.maxClipExtent, clipInfo.maxClipExtent * generatorParams.overallVolumeScalingReciprocal); MessageBox.Show(clippingMessage, "Clipping Ocurred", MessageBoxButtons.OK, MessageBoxIcon.Information); } }
public static void MainLoop<U>( WaveTableTestGeneratorParams<T, W> generatorParams, Synthesizer.DataOutCallbackMethod<OutputGeneric<T, U, W>> dataCallback, OutputGeneric<T, U, W> dataCallbackState, Synthesizer.StopTask stopper) { try { // Unoptimized - since only one runs at a time this codepath is not perf critical (unlike the // resampler loops in the synth engine) int NumTables = generatorParams.data.NumTables; float[][] ReferenceArray = new float[NumTables][]; for (int i = 0; i < NumTables; i++) { ReferenceArray[i] = generatorParams.data.ListOfTables[i].frames; } int PlaybackSamplingRate = generatorParams.samplingRate; if (PlaybackSamplingRate < Constants.MINSAMPLINGRATE) { PlaybackSamplingRate = Constants.MINSAMPLINGRATE; } if (PlaybackSamplingRate > Constants.MAXSAMPLINGRATE) { PlaybackSamplingRate = Constants.MAXSAMPLINGRATE; } int FramesPerTable = generatorParams.data.NumFrames; /* this is the initial index into the wave table */ Synthesizer.Fixed64 WaveformIndex = new Synthesizer.Fixed64(); /* this is the 16.16 bit fixed point number used to increment the index */ /* into the wave table */ Synthesizer.Fixed64 WaveformIncrementor = new Synthesizer.Fixed64( FramesPerTable * generatorParams.frequency / PlaybackSamplingRate); /* the number of times each wave slice has to be used */ int NumberOfIterationsAttack = (int)(generatorParams.attack * PlaybackSamplingRate); int NumberOfIterationsDecay = (int)(generatorParams.decay * PlaybackSamplingRate); const int SOUNDBUFFERLENGTHFRAMES = 256; float[] OutputBuffer = new float[SOUNDBUFFERLENGTHFRAMES * 2]; int OutputIndex = 0; for (int i = 0; i < NumberOfIterationsAttack + NumberOfIterationsDecay; i++) { /* compute wave table index for attack/decay phase */ double TableIndex; if (i < NumberOfIterationsAttack) { TableIndex = (double)i / NumberOfIterationsAttack; } else { TableIndex = (double)(NumberOfIterationsDecay + NumberOfIterationsAttack - i) / NumberOfIterationsDecay; } float Value = Synthesizer.WaveTableIndexer( WaveformIndex.Double, TableIndex * (NumTables - 1), NumTables, FramesPerTable, ReferenceArray, true/*EnableCrossWaveTableInterpolation*/); WaveformIndex += WaveformIncrementor; OutputBuffer[2 * OutputIndex + 0] = OutputBuffer[2 * OutputIndex + 1] = Value * .5f; OutputIndex++; if (OutputIndex == SOUNDBUFFERLENGTHFRAMES) { dataCallback( dataCallbackState, OutputBuffer, 0, SOUNDBUFFERLENGTHFRAMES); OutputIndex = 0; if (stopper.Stopped) { return; } } } dataCallback( dataCallbackState, OutputBuffer, 0, OutputIndex); } catch (Exception exception) { generatorParams.exception = exception; stopper.Stop(); } }
public static void MainLoop <U>( PlayFileWithEffectsGeneratorParams <T, W> generatorParams, Synthesizer.DataOutCallbackMethod <OutputGeneric <T, U, W> > dataCallback, OutputGeneric <T, U, W> dataCallbackState, Synthesizer.StopTask stopper) { try { generatorParams.result = Synthesizer.SynthStateRec.InitializeSynthesizer( out generatorParams.synthState, generatorParams.mainWindow.Document, new List <TrackObjectRec>(), null, 0 /*FrameToStartAt*/, generatorParams.reader.SamplingRate, 1 /*Oversampling*/, generatorParams.mainWindow.Document.EnvelopeUpdateRate, (LargeBCDType)generatorParams.mainWindow.Document.DefaultBeatsPerMinute, 1 /*OverallVolumeScalingReciprocal*/, (LargeBCDType)0d /*ScanningGap*/, out generatorParams.errorInfo, TextWriter.Synchronized(generatorParams.interactionLog), generatorParams.mainWindow.Document.Deterministic, generatorParams.mainWindow.Document.Seed, new Synthesizer.AutomationSettings()); if (generatorParams.result != Synthesizer.SynthErrorCodes.eSynthDone) { return; } // HACK! generatorParams.result = Synthesizer.NewTrackEffectGenerator( generatorParams.effectSpec, generatorParams.synthState.SynthParams0, out generatorParams.synthState.ScoreEffectProcessor); if (generatorParams.result != Synthesizer.SynthErrorCodes.eSynthDone) { return; } while (!stopper.Stopped) { // TODO: shouldn't ask for nAllocatedPointsOneChannel, that's slightly inaccurate. Should // use the clock logic in SynthGenerateOneCycle -- see e.g. nActualFrames int c; if (generatorParams.reader.NumChannels == NumChannelsType.eSampleMono) { c = generatorParams.reader.ReadPoints( generatorParams.synthState.SynthParams0.workspace, generatorParams.synthState.SynthParams0.ScoreWorkspaceLOffset, generatorParams.synthState.SynthParams0.nAllocatedPointsOneChannel); Synthesizer.FloatVectorCopy( generatorParams.synthState.SynthParams0.workspace, generatorParams.synthState.SynthParams0.ScoreWorkspaceLOffset, generatorParams.synthState.SynthParams0.workspace, generatorParams.synthState.SynthParams0.ScoreWorkspaceROffset, c); } else { c = generatorParams.reader.ReadPoints( generatorParams.synthState.SynthParams0.workspace, generatorParams.synthState.SynthParams0.SectionWorkspaceLOffset, generatorParams.synthState.SynthParams0.nAllocatedPointsOneChannel * 2); c /= 2; Synthesizer.FloatVectorMakeUninterleaved( generatorParams.synthState.SynthParams0.workspace, generatorParams.synthState.SynthParams0.SectionWorkspaceLOffset, generatorParams.synthState.SynthParams0.workspace, generatorParams.synthState.SynthParams0.ScoreWorkspaceLOffset, generatorParams.synthState.SynthParams0.workspace, generatorParams.synthState.SynthParams0.ScoreWorkspaceROffset, c); } if (c == 0) { break; } // HACK! // Should create specialized version of Synthesizer.SynthGenerateOneCycle that does this Synthesizer.UpdateStateTrackEffectGenerator( generatorParams.synthState.ScoreEffectProcessor, generatorParams.synthState.SynthParams0); Synthesizer.ApplyTrackEffectGenerator( generatorParams.synthState.ScoreEffectProcessor, generatorParams.synthState.SynthParams0.workspace, c, generatorParams.synthState.SynthParams0.ScoreWorkspaceLOffset, generatorParams.synthState.SynthParams0.ScoreWorkspaceROffset, generatorParams.synthState.SynthParams0); Synthesizer.FloatVectorMakeInterleaved( generatorParams.synthState.SynthParams0.workspace, generatorParams.synthState.SynthParams0.ScoreWorkspaceLOffset, generatorParams.synthState.SynthParams0.workspace, generatorParams.synthState.SynthParams0.ScoreWorkspaceROffset, c, generatorParams.synthState.SynthParams0.workspace, generatorParams.synthState.SynthParams0.SectionWorkspaceLOffset); dataCallback( dataCallbackState, generatorParams.synthState.SynthParams0.workspace, generatorParams.synthState.SynthParams0.SectionWorkspaceLOffset, c); } } catch (Exception exception) { generatorParams.exception = exception; stopper.Stop(); } }
private void Recalculate(bool updateInitialFinal) { recalcReentranceGuard++; try { if (recalcReentranceGuard == 1) { double duration; Double.TryParse(textBoxDuration.Text, out duration); double initial, final; Double.TryParse(textBoxInitial.Text, out initial); Double.TryParse(textBoxFinal.Text, out final); double newStart, newEnd; Double.TryParse(textBoxStartOffset.Text, out newStart); Double.TryParse(textBoxEndOffset.Text, out newEnd); bool exponential = comboBoxFunction.SelectedIndex != 0; double newInitial, newFinal; if (!exponential) { // linear newInitial = initial + newStart * (final - initial); newFinal = initial + newEnd * (final - initial); } else { // exponential double initialDecibels = Synthesizer.ExpSegEndpointToLog(initial); double finalDecibels = Synthesizer.ExpSegEndpointToLog(final); newInitial = initialDecibels + newStart * (finalDecibels - initialDecibels); newFinal = initialDecibels + newEnd * (finalDecibels - initialDecibels); newInitial = Synthesizer.ExpSegEndpointToLinear(newInitial); newFinal = Synthesizer.ExpSegEndpointToLinear(newFinal); } newInitial = Math.Round(newInitial, 8); newFinal = Math.Round(newFinal, 8); if (updateInitialFinal) { textBoxNewInitial.Text = newInitial.ToString(); textBoxNewFinal.Text = newFinal.ToString(); } statement = String.Format( "delay {0} level {1}{2};", duration * (newEnd - newStart), newFinal, exponential ? " exponential" : String.Empty); textBoxStatement.Text = String.Format( "[{0}]: {1}", newInitial, statement); segmentCalculatorGraph.Update(initial, final, duration, newStart, newEnd, exponential); savedInitial = initial; savedDelay = duration; savedFinal = final; savedExponential = exponential; savedNewStart = newStart; savedNewEnd = newEnd; } } finally { recalcReentranceGuard--; } }