Resampling and removing high frequency noise?
Sample playback

The basic idea of sample playback in musical applications is to keep track of each voice's playback position, to form an output sample by reading the source sample data at the playback position, to add a possibly time-varying playback step to the playback position, and to repeat this in a program loop until we have accumulated enough output samples for that voice. For multiple voices, their output samples are summed in a mixing buffer. If the output sampling frequency differs from the source sampling frequency, or if we want to play a different note than the source note, then playback step may be not equal to 1 (one source sample per one output sample), using your example scenario:

                source sampling frequency * desired note frequency
playback step = --------------------------------------------------
                output sampling frequency * source note frequency

                44100 Hz * 146.83 Hz
              = -------------------- = 0.56121239919
                44100 Hz * 261.63 Hz


If the playback step is not an integer, then the playback position will sometimes also be not an integer and we need to interpolate between the samples. It is also possible to do vibrato and tone portamento by varying the desired note frequency with time and consequently also varying the playback step, which will inevitably lead to a mostly non-integer playback position and the need for arbitrary sample rate conversion.

Interpolation, spectral images and aliasing

In this context, sampling is best understood (see Andreas Franck (2012) Efficient Algorithms for Arbitrary Sample Rate Conversion with Application to Wave Field Synthesis, section 3.4.1 Sample Rate Conversion as an Analog Resampling Process) as multiplication of a band-limited continuous-time audio signal by a Dirac comb and storing the integral over each scaled Dirac pulse in the resulting impulse train as the discrete-time sample data. The Fourier transform of the impulse train is periodic with a period of $2\pi$ in angular frequency. The chosen interpolation method is characterized by its continuous-time impulse response, and interpolation can be seen as convolution (filtering) of the impulse train by the continuous-time impulse response. The impulse response of a reasonable interpolation method is approximately low-pass, meaning that the convolution attenuates the spectral images (the duplicate spectra centered at multiples of $2\pi$). Then sampling of the approximately low-pass signal, at the playback positions encountered, will hopefully not lead to significant aliasing of the spectral images into the audio band.

If the bandwidth of the audio signal is half its sampling frequency, then a playback step > 1 will lead to aliasing of not only the spectral images, but also of some of the base-band audio frequencies. It helps to have an intermediate output sampling frequency where there is headroom for aliasing into a band above the audio frequencies that can be filtered away at an additional sample rate conversion to the final output sampling frequency. It is also possible to have multiple versions of the sample data that have been pre-filtered to reduce their bandwidth, to avoid aliasing when playback step > 1, similar to MIP mapping in computer graphics, see Laurent de Soras (2005) The Quest For The Perfect Resampler.

A time-varying playback step may further increase the continuous-time bandwidth, but usually the variation is slow enough that the playback step can be considered locally constant when it comes to bandwidth considerations.

Looping

Traditionally samplers have a number of ways of playing back sample data:


no loop (one-shot),
forward loop, with integer loop start and integer loop length (in sampling periods equal to 1 / sampling frequency, or the time difference between successive samples), and
ping-pong loop (forward-backward-...), with integer loop start and integer loop length (in one direction).


The forward loop requires a change in the program loop. If the playback position goes to the loop end (the first sample not included in the loop) or beyond it, then the loop length is subtracted from it. This works assuming that the playback step is smaller than the loop length. Ping-pong loop requires a bit more program logic, or the ping-pong loop can be unrolled into a forward loop. Upon note release, it is also possible to let the playback position escape the loop and to play the source sample data until the end.

Considering forward loops, when playing back the source sample data at its sampling frequency, what the loop length being an integer number of sampling periods means is that the period of the output waveform will be quantized to an integer multiple of the source sampling period. So it typically won't be possible to produce exactly the correct frequency, unless the source note frequency is a submultiple of the source sampling frequency. With your example, a loop length of 1000 sampling periods gives 261.63 Hz * 1000 / 44100 Hz = 5.932653 periods of the sine wave, so the last period will be cut short and give you a wide-band buzzing noise no matter what interpolation method you use.

Because of this inflexibility, we can bring into question whether the loop length should be an integer number of sampling periods. The benefit of a floating point (or a fixed point) loop length would be that we get a more correct note frequency, but the danger is that we introduce a discontinuity in the interpolated signal. With an integer loop length this discontinuity can be avoided by doing a short cross-fade of the loop start and end so that they have a few identical samples around them, as many as needed by the interpolation method. This way the interpolated curve will be exactly the same at the beginning and at the end of the loop. An alternative to cross-fading is to duplicate a few samples from the beginning of the loop at the loop end and in the following samples and to move the the loop slightly forward in time so that the interpolation method sees the same samples at the start and at the end of the loop. In case of a floating point loop start and loop length, they can be adjusted until no discontinuity can be heard, although this ties high loop quality to the present choice of the interpolation method.