Re #802 You can now choose to use or ignore partials phase during synthesis

git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/subprojects/soundeditor/trunk@5373 30fe4595-0a0c-4342-8851-515496e4dcbd
This commit is contained in:
pouillot 2013-03-30 14:27:47 +00:00 committed by Xavier Del Campo Romero
parent 7e46e37c17
commit 6d2a680a5c
Signed by: xavi
GPG Key ID: 84FF3612A9BF43F2
7 changed files with 100 additions and 46 deletions

View File

@ -142,11 +142,9 @@ void make_sine_table()
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
double ioscilator(double amp, double freq, double pha, double sr, double *oscpt) double ioscilator(double amp, double freq, double pha, double sr, double *oscpt)
{ {
const double incr = freq * (double)SINE_TABLE_LEN / sr;
// Phase management = 3 options (uncomment only one) : // Phase management = 3 options (uncomment only one) :
// 1) No phase = 0 phase. // 1) No phase = 0 phase.
const double osc = *oscpt; //const double osc = *oscpt;
// 2) Random phase. // 2) Random phase.
//static const int max_pha_shift = 300; //(SINE_TABLE_LEN / 2) / 1000; //static const int max_pha_shift = 300; //(SINE_TABLE_LEN / 2) / 1000;
@ -156,8 +154,8 @@ double ioscilator(double amp, double freq, double pha, double sr, double *oscpt)
//const double osc = fmod(*oscpt + SINE_TABLE_LEN + pha_shift, SINE_TABLE_LEN); //const double osc = fmod(*oscpt + SINE_TABLE_LEN + pha_shift, SINE_TABLE_LEN);
// 3) Shipped phase (linear interpolation). // 3) Shipped phase (linear interpolation).
//const int pha_shift = (int)(pha * (double)SINE_TABLE_LEN / TWO_PI); const int pha_shift = (int)(pha * (double)SINE_TABLE_LEN / TWO_PI);
//const double osc = fmod(*oscpt + SINE_TABLE_LEN + pha_shift, SINE_TABLE_LEN); const double osc = fmod(*oscpt + SINE_TABLE_LEN + pha_shift, SINE_TABLE_LEN);
double output; double output;
int curr_ind, next_ind; int curr_ind, next_ind;
@ -173,6 +171,7 @@ double ioscilator(double amp, double freq, double pha, double sr, double *oscpt)
* (osc - curr_ind)); * (osc - curr_ind));
// Update oscillator index. // Update oscillator index.
const double incr = freq * (double)SINE_TABLE_LEN / sr;
*oscpt = fmod(*oscpt + incr, SINE_TABLE_LEN); *oscpt = fmod(*oscpt + incr, SINE_TABLE_LEN);
return output; return output;
@ -262,12 +261,11 @@ double locate_frame(ATS_SOUND *ats_sound, double from_frame, double time)
} }
*/ */
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
//Synthesizes a Buffer NOT using phase interpolation
int synth_deterministic_only(double ampl_p, double ampl_c, double ampl_n, int synth_deterministic_only(double ampl_p, double ampl_c, double ampl_n,
double freq_p, double freq_c, double freq_n, double freq_p, double freq_c, double freq_n,
double pha_p, double pha_c, double pha_n, double pha_p, double pha_c, double pha_n,
double time_offset, double duration, double sample_rate, double time_offset, double duration, double sample_rate,
double *oscpt, double* sample_buf) short use_phase, double *oscpt, double* sample_buf)
{ {
int s, frame_samps; int s, frame_samps;
double ampl, freq, pha, frame_offset; double ampl, freq, pha, frame_offset;
@ -281,7 +279,7 @@ int synth_deterministic_only(double ampl_p, double ampl_c, double ampl_n,
frame_offset = (time_offset + s / sample_rate) / duration; frame_offset = (time_offset + s / sample_rate) / duration;
ampl = LIN3_INTERP(frame_offset, ampl_p, ampl_c, ampl_n); ampl = LIN3_INTERP(frame_offset, ampl_p, ampl_c, ampl_n);
freq = LIN3_INTERP(frame_offset, freq_p, freq_c, freq_n); freq = LIN3_INTERP(frame_offset, freq_p, freq_c, freq_n);
pha = 0; // Temporary: LIN3_INTERP(frame_offset, pha_p, pha_c, pha_n); pha = (use_phase ? LIN3_INTERP(frame_offset, pha_p, pha_c, pha_n) : 0.);
sample_buf[s] += ioscilator(ampl, freq, pha, sample_rate, oscpt); sample_buf[s] += ioscilator(ampl, freq, pha, sample_rate, oscpt);
} }
@ -304,7 +302,7 @@ int synth_residual_only(double ampl_p, double ampl_c, double ampl_n,
for(s = 0; s < frame_samps; s++) { for(s = 0; s < frame_samps; s++) {
frame_offset = (time_offset + s / sample_rate) / duration; frame_offset = (time_offset + s / sample_rate) / duration;
ampl = LIN3_INTERP(frame_offset, ampl_p, ampl_c, ampl_n); ampl = LIN3_INTERP(frame_offset, ampl_p, ampl_c, ampl_n);
pha = 0.; // Temporary. Should we use a random phase here ? pha = 0.; // Shouldn't we use a random phase here ?
sample_buf[s] += ioscilator(ampl, freq, pha, sample_rate, oscpt) * randi(rdata); sample_buf[s] += ioscilator(ampl, freq, pha, sample_rate, oscpt) * randi(rdata);
} }
@ -316,7 +314,7 @@ int synth_both(double ampl_p, double ampl_c, double ampl_n,
double pha_p, double pha_c, double pha_n, double pha_p, double pha_c, double pha_n,
double resid_p, double resid_c, double resid_n, double resid_p, double resid_c, double resid_n,
double time_offset, double duration, double sample_rate, double time_offset, double duration, double sample_rate,
double *oscpt, RANDI* rdata, double* sample_buf) short use_phase, double *oscpt, RANDI* rdata, double* sample_buf)
{ {
int s, frame_samps; int s, frame_samps;
double ampl, freq, pha, resid, rfreq, frame_offset; double ampl, freq, pha, resid, rfreq, frame_offset;
@ -336,7 +334,7 @@ int synth_both(double ampl_p, double ampl_c, double ampl_n,
frame_offset = (time_offset + s / sample_rate) / duration; frame_offset = (time_offset + s / sample_rate) / duration;
ampl = LIN3_INTERP(frame_offset, ampl_p, ampl_c, ampl_n); ampl = LIN3_INTERP(frame_offset, ampl_p, ampl_c, ampl_n);
freq = LIN3_INTERP(frame_offset, freq_p, freq_c, freq_n); freq = LIN3_INTERP(frame_offset, freq_p, freq_c, freq_n);
pha = 0; // Temporary: LIN3_INTERP(frame_offset, pha_p, pha_c, pha_n); pha = (use_phase ? LIN3_INTERP(frame_offset, pha_p, pha_c, pha_n) : 0.);
resid = LIN3_INTERP(frame_offset, resid_p, resid_c, resid_n); resid = LIN3_INTERP(frame_offset, resid_p, resid_c, resid_n);
rfreq = LIN3_INTERP(frame_offset, rfreq_p, rfreq_c, rfreq_n); rfreq = LIN3_INTERP(frame_offset, rfreq_p, rfreq_c, rfreq_n);
sample_buf[s] += sample_buf[s] +=
@ -392,7 +390,7 @@ void do_synthesis(ATS_SOUND *ats_sound, SPARAMS* sparams, CURVE* timenv, int *se
dur = sparams->end - sparams->beg; dur = sparams->end - sparams->beg;
todo=0; todo=0;
bframe = 0.; bframe = 0.;
fprintf(stdout, "do_synthesis: nbp=%d, dur=%f, dy=%f\n", nbp, dur, dy); fprintf(stdout, "do_synthesis: nbp=%d, dur=%f, dy=%f, pha=%d\n", nbp, dur, dy, sparams->upha);
for(p=0; p < nbp - 1; ++p){ for(p=0; p < nbp - 1; ++p){
@ -514,7 +512,7 @@ void do_synthesis(ATS_SOUND *ats_sound, SPARAMS* sparams, CURVE* timenv, int *se
if(sparams->ramp == 0.) { if(sparams->ramp == 0.) {
//deterministic synthesis only //deterministic synthesis only
for(d = 0; d < ats_sound->partials; d++) { for(d = 0; d < ats_sound->partials; d++) {
if (selected && !selected[d]) if (sparams->allorsel && selected && !selected[d])
continue; continue;
ampl_p = ats_sound->amp[d][f_p] * sparams->amp; ampl_p = ats_sound->amp[d][f_p] * sparams->amp;
ampl_c = ats_sound->amp[d][f] * sparams->amp; ampl_c = ats_sound->amp[d][f] * sparams->amp;
@ -527,7 +525,7 @@ void do_synthesis(ATS_SOUND *ats_sound, SPARAMS* sparams, CURVE* timenv, int *se
pha_n = ats_sound->pha[d][f_n]; pha_n = ats_sound->pha[d][f_n];
frame_samps = synth_deterministic_only(ampl_p, ampl_c, ampl_n, freq_p, freq_c, freq_n, frame_samps = synth_deterministic_only(ampl_p, ampl_c, ampl_n, freq_p, freq_c, freq_n,
pha_p, pha_c, pha_n, pha_p, pha_c, pha_n,
time_offset, duration, sparams->sr, time_offset, duration, sparams->sr, sparams->upha,
ospt+d, *out_samps + n_samps); ospt+d, *out_samps + n_samps);
} }
} else if(sparams->amp == 0.) { } else if(sparams->amp == 0.) {
@ -547,7 +545,7 @@ void do_synthesis(ATS_SOUND *ats_sound, SPARAMS* sparams, CURVE* timenv, int *se
} else { } else {
//residual and deterministic synthesis //residual and deterministic synthesis
for(d = 0; d < ats_sound->partials; d++) { for(d = 0; d < ats_sound->partials; d++) {
if (selected && !selected[d]) if (sparams->allorsel && selected && !selected[d])
continue; continue;
ampl_p = ats_sound->amp[d][f_p] * sparams->amp; ampl_p = ats_sound->amp[d][f_p] * sparams->amp;
ampl_c = ats_sound->amp[d][f] * sparams->amp; ampl_c = ats_sound->amp[d][f] * sparams->amp;
@ -566,7 +564,7 @@ void do_synthesis(ATS_SOUND *ats_sound, SPARAMS* sparams, CURVE* timenv, int *se
* sparams->ramp; * sparams->ramp;
frame_samps = synth_both(ampl_p, ampl_c, ampl_n, freq_p, freq_c, freq_n, frame_samps = synth_both(ampl_p, ampl_c, ampl_n, freq_p, freq_c, freq_n,
pha_p, pha_c, pha_n, resid_p, resid_c, resid_n, pha_p, pha_c, pha_n, resid_p, resid_c, resid_n,
time_offset, duration, sparams->sr, time_offset, duration, sparams->sr, sparams->upha,
ospt+d, &rarray[p], *out_samps + n_samps); ospt+d, &rarray[p], *out_samps + n_samps);
} }
} }

View File

@ -14,9 +14,9 @@
ATSSynthesis::ATSSynthesis(double dStartTime, double dDuration, ATSSynthesis::ATSSynthesis(double dStartTime, double dDuration,
bool bAllParts, bool bUsePartsPhase, bool bAllParts, bool bUsePartsPhase,
double dPartsAmplFactor, double dResidAmplFactor, double dPartsAmplFactor, double dResidAmplFactor,
double dFreqFactor, double dTimeFactor, double dFreqFactor, double dTimeFactor,
double dSampRate) double dSampRate)
{ {
setStartTime(dStartTime); setStartTime(dStartTime);
@ -48,14 +48,14 @@ ATSSynthesis& ATSSynthesis::operator=(const ATSSynthesis& src)
bool ATSSynthesis::operator==(const ATSSynthesis& src) const bool ATSSynthesis::operator==(const ATSSynthesis& src) const
{ {
return startTime() == src.startTime() return startTime() == src.startTime()
&& duration() == src.duration() && duration() == src.duration()
&& useOnlySelectedPartials() == src.useOnlySelectedPartials() && useOnlySelectedPartials() == src.useOnlySelectedPartials()
&& usePartialsPhase() == src.usePartialsPhase() && usePartialsPhase() == src.usePartialsPhase()
&& partialsAmplitudeFactor() == src.partialsAmplitudeFactor() && partialsAmplitudeFactor() == src.partialsAmplitudeFactor()
&& residualAmplitudeFactor() == src.residualAmplitudeFactor() && residualAmplitudeFactor() == src.residualAmplitudeFactor()
&& frequencyFactor() == src.frequencyFactor() && frequencyFactor() == src.frequencyFactor()
&& timeFactor() == src.timeFactor() && timeFactor() == src.timeFactor()
&& samplingRate() == src.samplingRate(); && samplingRate() == src.samplingRate();
} }
bool ATSSynthesis::operator!=(const ATSSynthesis& src) const bool ATSSynthesis::operator!=(const ATSSynthesis& src) const
@ -92,15 +92,14 @@ SampledSound* ATSSynthesis::operator()(ATSSound* pATSSound, const std::vector<in
(pATSSound->data(), &_params, &timeEnvelop, aSelectedPartials, (pATSSound->data(), &_params, &timeEnvelop, aSelectedPartials,
&adSamples[0], &nSamples); &adSamples[0], &nSamples);
curve_free(&timeEnvelop); curve_free(&timeEnvelop);
if (aSelectedPartials) delete [] aSelectedPartials;
delete [] aSelectedPartials;
// Build a SampleSound from these samples (monophonic => 1 channel). // Build a SampleSound from these samples (monophonic => 1 channel).
SampledSound* pSampSound = 0; SampledSound* pSampSound = 0;
if (adSamples[0] && nSamples > 0) if (adSamples[0] && nSamples > 0)
{ {
pSampSound = new SampledSound(1, nSamples, (int)samplingRate(), adSamples); pSampSound = new SampledSound(1, nSamples, (int)samplingRate(), adSamples);
free(adSamples[0]); free(adSamples[0]);
} }
return pSampSound; return pSampSound;

View File

@ -20,9 +20,9 @@ class ATSSynthesis
{ {
public: public:
ATSSynthesis(double dStartTime=0.0, double dDuration=0.0, ATSSynthesis(double dStartTime=0.0, double dDuration=0.0,
bool bAllParts=true, bool bUsePartsPhase=false, bool bAllParts=true, bool bUsePartsPhase=false,
double dPartsAmplFactor=1.0, double dResidAmplFactor=1.0, double dPartsAmplFactor=1.0, double dResidAmplFactor=1.0,
double dFreqFactor=1.0, double dTimeFactor=1.0, double dFreqFactor=1.0, double dTimeFactor=1.0,
double dSampRate=44100); double dSampRate=44100);
SampledSound* operator()(ATSSound* pATSSound, const std::vector<int>& vecSelPartIndexes); SampledSound* operator()(ATSSound* pATSSound, const std::vector<int>& vecSelPartIndexes);

View File

@ -281,7 +281,7 @@ bool DocumentWindow::synthesiseFile(const QString &qsFileName,
// Free now useless sampled sound. // Free now useless sampled sound.
delete pSampSound; delete pSampSound;
// Save a copy of the synthesis inputs for later. // Save a copy of the synthesis inputs for later.
_qsLastSyntResFileName = qsFileName; _qsLastSyntResFileName = qsFileName;
if (!_pLastSyntParams) if (!_pLastSyntParams)
_pLastSyntParams = new ATSSynthesis(); _pLastSyntParams = new ATSSynthesis();

View File

@ -26,8 +26,6 @@ SynthesisParamsWidget::SynthesisParamsWidget(QWidget *parent)
SynthesisParamsWidget::~SynthesisParamsWidget() SynthesisParamsWidget::~SynthesisParamsWidget()
{ {
delete _pui; delete _pui;
if (_pSynthesis)
delete _pSynthesis; delete _pSynthesis;
} }
@ -51,6 +49,7 @@ void SynthesisParamsWidget::onRestoreDefaults()
_pui->qsbStartTime->setValue(0.0); _pui->qsbStartTime->setValue(0.0);
_pui->qsbDuration->setValue(_dMaxDuration); _pui->qsbDuration->setValue(_dMaxDuration);
_pui->qrbAllPartials->setChecked(!synt.useOnlySelectedPartials()); _pui->qrbAllPartials->setChecked(!synt.useOnlySelectedPartials());
_pui->qrbUsePhase->setChecked(synt.usePartialsPhase());
_pui->qsbPartAmplFactor->setValue(synt.partialsAmplitudeFactor()); _pui->qsbPartAmplFactor->setValue(synt.partialsAmplitudeFactor());
_pui->qsbResidAmplFactor->setValue(synt.residualAmplitudeFactor()); _pui->qsbResidAmplFactor->setValue(synt.residualAmplitudeFactor());
_pui->qsbFreqFactor->setValue(synt.frequencyFactor()); _pui->qsbFreqFactor->setValue(synt.frequencyFactor());
@ -76,11 +75,12 @@ void SynthesisParamsWidget::setMaxDuration(double dMaxDuration)
void SynthesisParamsWidget::setupSynthesis() void SynthesisParamsWidget::setupSynthesis()
{ {
if (!_pSynthesis) if (!_pSynthesis)
_pSynthesis = new ATSSynthesis(); _pSynthesis = new ATSSynthesis();
_pSynthesis->setStartTime(_pui->qsbStartTime->value()); _pSynthesis->setStartTime(_pui->qsbStartTime->value());
_pSynthesis->setDuration(_pui->qsbDuration->value()); _pSynthesis->setDuration(_pui->qsbDuration->value());
_pSynthesis->setUseOnlySelectedPartials(!_pui->qrbAllPartials->isChecked()); _pSynthesis->setUseOnlySelectedPartials(!_pui->qrbAllPartials->isChecked());
_pSynthesis->setUsePartialsPhase(_pui->qrbUsePhase->isChecked());
_pSynthesis->setPartialsAmplitudeFactor(_pui->qsbPartAmplFactor->value()); _pSynthesis->setPartialsAmplitudeFactor(_pui->qsbPartAmplFactor->value());
_pSynthesis->setResidualAmplitudeFactor(_pui->qsbResidAmplFactor->value()); _pSynthesis->setResidualAmplitudeFactor(_pui->qsbResidAmplFactor->value());
_pSynthesis->setFrequencyFactor(_pui->qsbFreqFactor->value()); _pSynthesis->setFrequencyFactor(_pui->qsbFreqFactor->value());

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>302</width> <width>302</width>
<height>191</height> <height>230</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -101,6 +101,9 @@
<property name="checked"> <property name="checked">
<bool>true</bool> <bool>true</bool>
</property> </property>
<attribute name="buttonGroup">
<string notr="true">bgPartials</string>
</attribute>
</widget> </widget>
</item> </item>
<item row="2" column="2"> <item row="2" column="2">
@ -111,16 +114,67 @@
<property name="text"> <property name="text">
<string>Selection</string> <string>Selection</string>
</property> </property>
<attribute name="buttonGroup">
<string notr="true">bgPartials</string>
</attribute>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_8">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Use partials phase</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QRadioButton" name="qrbUsePhase">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Yes</string>
</property>
<attribute name="buttonGroup">
<string notr="true">bgPhase</string>
</attribute>
</widget>
</item>
<item row="3" column="2">
<widget class="QRadioButton" name="qrbIgnorePhase">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>No</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">bgPhase</string>
</attribute>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="text"> <property name="text">
<string>Partials amplitude factor</string> <string>Partials amplitude factor</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1" colspan="2"> <item row="4" column="1" colspan="2">
<widget class="QDoubleSpinBox" name="qsbPartAmplFactor"> <widget class="QDoubleSpinBox" name="qsbPartAmplFactor">
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -136,14 +190,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0"> <item row="5" column="0">
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_2">
<property name="text"> <property name="text">
<string>Residual amplitude factor</string> <string>Residual amplitude factor</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="1" colspan="2"> <item row="5" column="1" colspan="2">
<widget class="QDoubleSpinBox" name="qsbResidAmplFactor"> <widget class="QDoubleSpinBox" name="qsbResidAmplFactor">
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -159,14 +213,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="0"> <item row="6" column="0">
<widget class="QLabel" name="label_3"> <widget class="QLabel" name="label_3">
<property name="text"> <property name="text">
<string>Frequency factor</string> <string>Frequency factor</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="1" colspan="2"> <item row="6" column="1" colspan="2">
<widget class="QDoubleSpinBox" name="qsbFreqFactor"> <widget class="QDoubleSpinBox" name="qsbFreqFactor">
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -185,14 +239,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="0"> <item row="7" column="0">
<widget class="QLabel" name="label_4"> <widget class="QLabel" name="label_4">
<property name="text"> <property name="text">
<string>Sampling rate</string> <string>Sampling rate</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="1" colspan="2"> <item row="7" column="1" colspan="2">
<widget class="QDoubleSpinBox" name="qsbSamplingRate"> <widget class="QDoubleSpinBox" name="qsbSamplingRate">
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -217,4 +271,8 @@
</widget> </widget>
<resources/> <resources/>
<connections/> <connections/>
<buttongroups>
<buttongroup name="bgPartials"/>
<buttongroup name="bgPhase"/>
</buttongroups>
</ui> </ui>

View File

@ -57,7 +57,6 @@ TableAndToolsWidget::TableAndToolsWidget(QWidget *parent)
TableAndToolsWidget::~TableAndToolsWidget() TableAndToolsWidget::~TableAndToolsWidget()
{ {
delete _pui; delete _pui;
if (_pProcessor)
delete _pProcessor; delete _pProcessor;
} }