title: FFmpeg - resampling from AV_SAMPLE_FMT_FLTP to AV_SAMPLE_FMT_S16 got very bad sound quality (slow, out of tune, noise)
body: <p>I was confused with resampling result in new ffmpeg.
  I decode an AAC audio into PCM, the ffmpeg show audio information as:</p>
  
  <pre><code>Stream #0:0: Audio: aac, 44100 Hz, stereo, fltp, 122 kb/s
  </code></pre>
  
  <p>In new ffmpeg, the output samples are fltp format, so I have to convert it from AV_SAMPLE_FMT_FLTP to AV_SAMPLE_FMT_S16 </p>
  
  <p><strong>PS: in old ffmpeg as libavcodec 54.12.100, it is directly S16, so do not need resampling and without any sound quality problem</strong>. </p>
  
  <p>Then I've tried three ways to resampling, </p>
  
  <ol>
  <li><p>using swr_convert</p></li>
  <li><p>using avresample_convert</p></li>
  <li><p>convert manualy</p></li>
  </ol>
  
  <p>But all of them yield the same result, the sound quality is really bad, very slow and out of tune, with some noise too. </p>
  
  <p>My resampling code is as follows: </p>
  
  <pre><code>void resampling(AVFrame* frame_, AVCodecContext* pCodecCtx, int64_t want_sample_rate, uint8_t* outbuf){
      SwrContext      *swrCtx_ = 0;
      AVAudioResampleContext *avr = 0;
  
      // Initializing the sample rate convert. We only really use it to convert float output into int.
      int64_t wanted_channel_layout = AV_CH_LAYOUT_STEREO;
  
  #ifdef AV_SAMPLEING
      avr = avresample_alloc_context();
      av_opt_set_int(avr, "in_channel_layout", frame_-&gt;channel_layout, 0);
      av_opt_set_int(avr, "out_channel_layout", wanted_channel_layout, 0);
      av_opt_set_int(avr, "in_sample_rate", frame_-&gt;sample_rate, 0);
      av_opt_set_int(avr, "out_sample_rate", 44100, 0);
      av_opt_set_int(avr, "in_sample_fmt", pCodecCtx-&gt;sample_fmt, 0); //AV_SAMPLE_FMT_FLTP
      av_opt_set_int(avr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
      av_opt_set_int(avr, "internal_sample_fmt", pCodecCtx-&gt;sample_fmt, 0);
      avresample_open(avr);
      avresample_convert(avr, &amp;outbuf, frame_-&gt;linesize[0], frame_-&gt;nb_samples, frame_-&gt;extended_data, frame_-&gt;linesize[0], frame_-&gt;nb_samples);
      avresample_close(avr);
      return;
  #endif
  
  #ifdef USER_SAMPLEING
      if (pCodecCtx-&gt;sample_fmt == AV_SAMPLE_FMT_FLTP)
      {
              int nb_samples = frame_-&gt;nb_samples;
              int channels = frame_-&gt;channels;
              int outputBufferLen = nb_samples &amp; channels * 2;
              auto outputBuffer = (int16_t*)outbuf;
  
              for (int i = 0; i &lt; nb_samples; i++)
              {
                      for (int c = 0; c &lt; channels; c++)
                      {
                              float* extended_data = (float*)frame_-&gt;extended_data[c];
                              float sample = extended_data[i];
                              if (sample &lt; -1.0f) sample = -1.0f;
                              else if (sample &gt; 1.0f) sample = 1.0f;
                              outputBuffer[i * channels + c] = (int16_t)round(sample * 32767.0f);
                      }
              }
              return;
      }
  #endif
      swrCtx_ = swr_alloc_set_opts(
              NULL, //swrCtx_,
              wanted_channel_layout,
              AV_SAMPLE_FMT_S16,
              want_sample_rate,
              pCodecCtx-&gt;channel_layout,
              pCodecCtx-&gt;sample_fmt,
              pCodecCtx-&gt;sample_rate,
              0,
              NULL);
  
      if (!swrCtx_ || swr_init(swrCtx_) &lt; 0) {
              printf("swr_init: Failed to initialize the resampling context");
              return;
      }
  
      // convert audio to AV_SAMPLE_FMT_S16
      int swrRet = swr_convert(swrCtx_, &amp;outbuf, frame_-&gt;nb_samples, (const uint8_t **)frame_-&gt;extended_data, frame_-&gt;nb_samples);
      if (swrRet &lt; 0) {
              printf("swr_convert: Error while converting %d", swrRet);
              return;
      }
  }
  </code></pre>
  
  <p>What should to do?</p>
  
  <p>PS1: playing with ffplay is just all right.</p>
  
  <p>PS2: save resample S16 PCM into file and playing it will have the same sound quality problem.</p>
  
  <p>Thanks a lot for your help and suggestions!</p>
  
  <hr>
  
  <p>I've also noticed that, in old ffmpeg, aac is recongized as FLT format and directly decoded into 16-bit PCM, while in new ffmpeg, aac is counted as FLTP format and produce still 32-bit IEEE float output.</p>
  
  <p>Thus the same code will produce quite different outputs with different versions of ffmpeg.
  Then, <strong>I'd like to ask what is the right way to convert a AAC audio to 16-bit PCM in new version?</strong> </p>
  
  <p>Thanks a lot in advance!</p>