% Render a cymbal crash with default parameters and print diagnostics. % Set P.strike_count = 8 for a repeated ride figure, P.strike_r = 0.1 for the % bell, P.strike_velocity = 0.7 for a tap on the same instrument, or % P.cascade_gain = 0 to hear the plate as an exactly linear resonator. Setting % P.hammer_mix = 0 recovers the ideal axisymmetric plate, which is worth % hearing once: it is a bell, because only its lowest few nodal-diameter % orders can radiate at all. % Run with: numbl run cymbal_demo.m P = cymbal_defaults(); tic; [y, basis, dinfo] = cymbal_render(P); elapsed = toc; fprintf('modes kept : %d up to n = %d nodal diameters (%.0f Hz to %.0f Hz)\n', ... dinfo.modesKept, dinfo.maxN, basis.f(1), basis.f(end)); fprintf('lowest : '); fprintf('%.0f ', basis.f(1:min(10, basis.n))); fprintf('Hz\n'); fprintf('contact : r = %.1f cm (%.1f cm in from the rim, %s)', ... dinfo.strikeRadiusM * 100, dinfo.strikeRimM * 100, cd_region(P, dinfo.strikeRadiusM)); if dinfo.strikeCount > 1 fprintf(', alternating with r = %.1f cm (%s)', ... dinfo.roll2RadiusM * 100, cd_region(P, dinfo.roll2RadiusM)); end fprintf('\n'); fprintf('strikes : %d at %.1f Hz (mean v %.2f m/s, mean contact %.0f us, peak force %.0f N)\n', ... dinfo.strikeCount, P.strike_rate_hz, dinfo.meanV, dinfo.meanTauUs, dinfo.peakForceN); fprintf('cascade : peak w_rms %.1f um = %.2f thicknesses, %.1f%% of the injected energy left the top\n', ... dinfo.peakWrmsUm, sqrt(dinfo.peakStrength), 100 * dinfo.cascadeLostJ / max(1e-30, dinfo.injectedJ)); fprintf('peak press.: %.4f Pa (%.1f dB SPL) at %.0f cm\n', ... dinfo.peakPa, dinfo.peakSplDb, dinfo.listenerDistM * 100); fprintf('length : %.2f s @ %d Hz\n', length(y) / P.sample_rate, P.sample_rate); fprintf('render time: %.2f s\n', elapsed); if dinfo.listenerInside fprintf('WARNING : listener is at or inside the plate\n'); end function s = cd_region(P, r) % Which part of the instrument a contact radius falls on. if r <= P.bell_radius_m s = 'bell'; elseif r >= P.radius_m - 0.045 s = 'edge'; else s = 'bow'; end end