void structScriptEditor :: v_destroy () { Melder_free (environmentName); forget (interpreter); if (theScriptEditors) Collection_undangleItem (theScriptEditors, this); ScriptEditor_Parent :: v_destroy (); }
void LongSound_playPart (LongSound me, double tmin, double tmax, Sound_PlayCallback callback, Thing boss) { struct LongSoundPlay *thee = (struct LongSoundPlay *) & thePlayingLongSound; MelderAudio_stopPlaying (MelderAudio_IMPLICIT); Melder_free (thy resampledBuffer); // just in case, and after playing has stopped try { int fits = LongSound_haveWindow (me, tmin, tmax); long bestSampleRate = MelderAudio_getOutputBestSampleRate (my sampleRate), n, i1, i2; if (! fits) Melder_throw (U"Sound too long (", tmax - tmin, U" seconds)."); /* * Assign to *thee only after stopping the playing sound. */ thy tmin = tmin; thy tmax = tmax; thy callback = callback; thy boss = boss; if ((n = Sampled_getWindowSamples (me, tmin, tmax, & i1, & i2)) < 2) return; if (bestSampleRate == my sampleRate) { thy numberOfSamples = n; thy dt = 1 / my sampleRate; thy t1 = my x1; thy i1 = i1; thy i2 = i2; thy silenceBefore = (long) (my sampleRate * MelderAudio_getOutputSilenceBefore ()); thy silenceAfter = (long) (my sampleRate * MelderAudio_getOutputSilenceAfter ()); if (thy callback) thy callback (thy boss, 1, tmin, tmax, tmin); if (thy silenceBefore > 0 || thy silenceAfter > 0 || 1) { thy resampledBuffer = Melder_calloc (int16, (thy silenceBefore + thy numberOfSamples + thy silenceAfter) * my numberOfChannels); memcpy (& thy resampledBuffer [thy silenceBefore * my numberOfChannels], & my buffer [(i1 - my imin) * my numberOfChannels], thy numberOfSamples * sizeof (int16) * my numberOfChannels); MelderAudio_play16 (thy resampledBuffer, my sampleRate, thy silenceBefore + thy numberOfSamples + thy silenceAfter, my numberOfChannels, melderPlayCallback, thee); } else { MelderAudio_play16 (my buffer + (i1 - my imin) * my numberOfChannels, my sampleRate, thy numberOfSamples, my numberOfChannels, melderPlayCallback, thee); } } else { long newSampleRate = bestSampleRate; long newN = ((double) n * newSampleRate) / my sampleRate - 1; long silenceBefore = (long) (newSampleRate * MelderAudio_getOutputSilenceBefore ()); long silenceAfter = (long) (newSampleRate * MelderAudio_getOutputSilenceAfter ()); int16 *resampledBuffer = Melder_calloc (int16, (silenceBefore + newN + silenceAfter) * my numberOfChannels); int16 *from = my buffer + (i1 - my imin) * my numberOfChannels; // guaranteed: from [0 .. (my imax - my imin + 1) * nchan] double t1 = my x1, dt = 1.0 / newSampleRate; thy numberOfSamples = newN; thy dt = dt; thy t1 = t1 + i1 / my sampleRate; thy i1 = 0; thy i2 = newN - 1; thy silenceBefore = silenceBefore; thy silenceAfter = silenceAfter; thy resampledBuffer = resampledBuffer; if (my numberOfChannels == 1) { for (long i = 0; i < newN; i ++) { double t = t1 + i * dt; // from t1 to t1 + (newN-1) * dt double index = (t - t1) * my sampleRate; // from 0 long flore = index; // DANGEROUS: Implicitly rounding down... double fraction = index - flore; resampledBuffer [i + silenceBefore] = (1.0 - fraction) * from [flore] + fraction * from [flore + 1]; } } else if (my numberOfChannels == 2) { for (long i = 0; i < newN; i ++) { double t = t1 + i * dt; double index = (t - t1) * my sampleRate; long flore = index; double fraction = index - flore; long ii = i + silenceBefore; resampledBuffer [ii + ii] = (1.0 - fraction) * from [flore + flore] + fraction * from [flore + flore + 2]; resampledBuffer [ii + ii + 1] = (1.0 - fraction) * from [flore + flore + 1] + fraction * from [flore + flore + 3]; } } else { for (long i = 0; i < newN; i ++) { double t = t1 + i * dt; double index = (t - t1) * my sampleRate; long flore = index; double fraction = index - flore; long ii = (i + silenceBefore) * my numberOfChannels; for (long chan = 0; chan < my numberOfChannels; chan ++) { resampledBuffer [ii + chan] = (1.0 - fraction) * from [flore * my numberOfChannels + chan] + fraction * from [(flore + 1) * my numberOfChannels + chan]; } } } if (thy callback) thy callback (thy boss, 1, tmin, tmax, tmin); MelderAudio_play16 (resampledBuffer, newSampleRate, silenceBefore + newN + silenceAfter, my numberOfChannels, melderPlayCallback, thee); } //Melder_free (thy resampledBuffer); // cannot do that, because MelderAudio_play16 isn't necessarily synchronous } catch (MelderError) { Melder_free (thy resampledBuffer); Melder_throw (me, U": not played."); } }