Azimer / AziAudio

Azimer's Audio Plugin
GNU General Public License v2.0
46 stars 11 forks source link

Implement different interpolation methods #4

Open Azimer opened 5 years ago

Azimer commented 5 years ago

I carry over from Discord discussion from kimbjo, retroben and DKO. Pasted here for further discussion and further consideration. I have some very basic resampling code in for wasapi but it could certainly use a quality bump. If such a thing was implemented it would be optional.

How much work would require to implement different interpolation methods to improve the audio quality? I think Catmull-Rom is one of the best. Directsound enforces linear interpolation to match the speaker frequency, which sounds crappy and muffled. XAudio2 and WASAPI don't seem to use linear interpolation, they sound better. By default, Directsound in Windows XP used 'high-end multipoint interpolation', but after Windows Vista when they dropped Hardware accelerated audio, they use linear interpolation, which was the lowest option in this slider tagoreillycom20070314oreillyimages176469 That's basically the audio equivalent of setting jpeg compression to the lowest quality and leaving on that setting that does the opposite of saving space/what its supposed to do all while leaving discolored artifacts and costing more space. Fraunhofer even made an article talking about it, here https://www2.iis.fraunhofer.de/AAC/ie9.html I'm really dissapointed that Microsoft dropped hardware acceleration support for audio, which allowed for really low latencies and real-time audio processing, 3D effects, reverberation, etc. I was looking at PCSX2's code and VBA-M's audio backend code, they both seem be doing interpolation on software level unknown This seems to be a good reference for audio interpolation (paper and code available): http://yehar.com/blog/?p=197 But if you don't want to write resampling code yourself, it seems this is the go-to option: https://sourceforge.net/projects/soxr/ It has SIMD optimizations and OpenMP support (so each channel can be ressampled in parallel.)

#if defined _OPENMP
  int i;
  if (!p->runtime_spec.num_threads && p->num_channels > 1)
#pragma omp parallel for
  for (i = 0; i < (int)p->num_channels; ++i) {
    size_t done1;
    done1 = soxr_output_1ch(p, (unsigned)i, ((soxr_bufs_t)out)[i], len, separated);
    if (!i)
      done = done1;
  } else
#endif