Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

AudioPlayer and differents WAV playing #2014

Answered by pschatzmann
hash6iron asked this question in Q&A
Discussion options

Hello @pschatzmann,

I'm trying to play several WAV with differentes bits per samples, sampling rate, etc, but only 16bits/22Khz play well the others else play wrongs. What I should be into account to play WAV correctly depending of the WAV file setting?

Thanks in advance.

You must be logged in to vote

I am not sure what you are doing wrong: but this should definitly work!

Replies: 12 comments · 18 replies

Comment options

I am not sure what you are doing wrong: but this should definitly work!

You must be logged in to vote
3 replies
@hash6iron
Comment options

Ok.

Please show me an example with AudioPlayer to compare, because mp3 works fine but WAV not, and the code is same for both media types.

@pschatzmann
Comment options

You can take any example and just replace the extension filter with wav and the decoder with a WAVDecoder.
If you have a slow drive make sure that you set the log level to Warning because WAV needs to process much more data then mp3.
In log level info, you can check if the i2s gets the correct audio info from the WAV header....

@hash6iron
Comment options

Ok. Thanks. I try that again.

Answer selected by pschatzmann
Comment options

Hi @pschatzmann ,

The log says me following:

[I] CodecWAV.h : 57 - WAVHeader::begin: 200
[I] CodecWAV.h : 212 - WAVHeader sound_pos: 44
[I] CodecWAV.h : 213 - WAVHeader channels: 1 
[I] CodecWAV.h : 214 - WAVHeader bits_per_sample: 8
[I] CodecWAV.h : 215 - WAVHeader sample_rate: 22050
[I] CodecWAV.h : 216 - WAVHeader format: 1
[I] CodecWAV.h : 421 - WAV sample_rate: 22050
[I] CodecWAV.h : 422 - WAV data_length: 4294967295
[I] CodecWAV.h : 423 - WAV is_streamed: 1
[I] CodecWAV.h : 425 - WAV is_valid: false
[I] I2SCodecStream.h : 95 - virtual void audio_tools::I2SCodecStream::setAudioInfo(audio_tools::AudioInfo)
[D] BaseStream.h : 128 - virtual void audio_tools::AudioStream::setAudioInfo(audio_tools::AudioInfo)
[I] AudioTypes.h : 125 - in: sample_rate: 22050 / channels: 1 / bits_per_sample: 8
[I] AudioTypes.h : 125 - out: sample_rate: 22050 / channels: 1 / bits_per_sample: 8
[I] I2SStream.h : 96 - virtual void audio_tools::I2SStream::setAudioInfo(audio_tools::AudioInfo)
[D] BaseStream.h : 128 - virtual void audio_tools::AudioStream::setAudioInfo(audio_tools::AudioInfo)
[I] AudioTypes.h : 125 - in: sample_rate: 22050 / channels: 1 / bits_per_sample: 8
[I] AudioTypes.h : 125 - out: sample_rate: 22050 / channels: 1 / bits_per_sample: 8
[I] I2SStream.h : 105 - restarting i2s
[I] AudioTypes.h : 125 - I2SStream sample_rate: 22050 / channels: 1 / bits_per_sample: 8
[D] I2SESP32.h : 88 - void audio_tools::I2SDriverESP32::end()
[D] I2SESP32.h : 63 - bool audio_tools::I2SDriverESP32::begin(audio_tools::I2SConfigESP32)
[D] I2SESP32.h : 182 - bool audio_tools::I2SDriverESP32::begin(audio_tools::I2SConfigESP32, int, int)
[I] AudioTypes.h : 125 -  sample_rate: 22050 / channels: 1 / bits_per_sample: 8
[I] I2SConfigESP32.h : 80 - rx/tx mode: RXTX_MODE
[I] I2SConfigESP32.h : 81 - port_no: 0
[I] I2SConfigESP32.h : 82 - is_master: Master
[I] I2SConfigESP32.h : 83 - sample rate: 22050
[I] I2SConfigESP32.h : 84 - bits per sample: 8
[I] I2SConfigESP32.h : 85 - number of channels: 1
[I] I2SConfigESP32.h : 86 - signal_type: Digital
[I] I2SConfigESP32.h : 88 - i2s_format: I2S_STD_FORMAT
[I] I2SConfigESP32.h : 90 - auto_clear: true
[I] I2SConfigESP32.h : 97 - buffer_count:6
[I] I2SConfigESP32.h : 98 - buffer_size:512
[I] I2SConfigESP32.h : 101 - pin_mck: 0
[I] I2SConfigESP32.h : 103 - pin_bck: 27
[I] I2SConfigESP32.h : 105 - pin_ws: 25
[I] I2SConfigESP32.h : 107 - pin_data: 26
[I] I2SConfigESP32.h : 109 - pin_data_rx: 35
[D] I2SESP32.h : 214 - i2s_driver_install
[D] I2SESP32.h : 230 - i2s_set_pin
[D] I2SESP32.h : 241 - i2s_zero_dma_buffer
[D] I2SESP32.h : 245 - begin - started
[E] I2SCodecStream.h : 327 - Unsupported bits: 8
[D] I2SCodecStream.h : 344 - RATE_22K
[D] AudioEncoded.h : 187 - EncodedAudioOutput::write: 1024 -> 1024
[D] StreamCopy.h : 398 - write: 1024 -> 1024
[I] StreamCopy.h : 173 - StreamCopy::copy  1024 -> 1024 -> 1024 bytes - in 1 hops

I have noticed that I2SCodecStream says me that not supports 8-bits. I don't understand.

You must be logged in to vote
0 replies
Comment options

Anyway I test with 16-bits mono WAV file at 22KHz and the output is not adapted to 22KHz for sampling rate, the output is always in 44.1KHz. Else I used addNotifyAudioChange(kitStream); where kitStream is AudioBoardStream kitStream(powadcr_board);

You must be logged in to vote
6 replies
@hash6iron
Comment options

The problem is, although I use 16-bit WAV at 22KHz the pipe not update to 22KHz and keep in 44.1KHz. The playing is slowed down.

@pschatzmann
Comment options

I think we are turing in circles, so again: can you show this in the log ?
Are you outputting directly to AudioBoardStream ?
Did you try an example with 2 channels ?

@hash6iron
Comment options

Yes I output directly AudioBoardStream. would I need I2SCodeStrem too?

@pschatzmann
Comment options

No, that does not make any difference...

@hash6iron
Comment options

And I'm using Notify to AudioBoardStream to update sample rate.

Comment options

Hi @pschatzmann,

I don't know from where the problem comes. This below is my media player. With MP3 appears works fine but not with WAV. If some WAV of the directory is at 22.1KHz the output is not adapted to this sampling rate, and plays slowed down.

have a look. To test it you only need a kitStream object as AudioBoardStream, all rest of mediaplayer is content in this following method.

Put ACTIVE_AMP as false
Put MAIN_VOL as 1
Put EJECT or STOP as exit conditions of the WHILE loop.

If you want you can used my code (optimized by you or not) for complete PLAYER example.

void MediaPlayer(bool isWav = false) {
    
    // Generamos el media descriptor
    String mediapath = "";
    File32 file;
    mediapath = FILE_LAST_DIR + "_files.lst";
    if(!file.open(mediapath.c_str(), O_RDONLY))
    {
      LAST_MESSAGE = "Error opening file list";
      return;
    }
    // else
    // {
    //   // Llenamos la playlist
    //   // fillMediaDescriptor(file, isWav);
    // }

    // Setup
    // Configuramos el amplificador de salida
    kitStream.setPAPower(ACTIVE_AMP);
    kitStream.setVolume(MAIN_VOL / 100);

    // Configuración de la fuente de audio
    AudioSourceSDFAT source(sdf);
    source.setPath(FILE_LAST_DIR.c_str());
    source.setFileFilter(isWav ? "*.wav" : "*.mp3");
    // Configuración del decodificador
    MP3DecoderHelix decoderMP3;
    WAVDecoder decoderWAV;
    MetaDataFilterDecoder metadatafilter(decoderMP3);
    metadatafilter.addNotifyAudioChange(kitStream);
    //metadatafilter.begin();

    // Usamos un puntero a la clase base común
    // AudioDecoder decoderMP3;
    // AudioDecoder decoderWAV;
    //AudioDecoder *decoder = isWav ? static_cast<AudioDecoder*>(&decoderWAV) : static_cast<AudioDecoder*>(&metadatafilter);

    // Configuración del reproductor
    AudioPlayer player;
    player.setAudioSource(source);
    player.setOutput(kitStream);
    if (isWav)
    {
      player.setDecoder(decoderWAV); // Usamos el puntero al decodificador WAV
    }
    else
    {
      player.setDecoder(metadatafilter); // Usamos el puntero al decodificador MP3
    }

    //player.setDecoder(*decoder); // Usamos el puntero al decodificador
    player.setVolume(1);
    player.setBufferSize(512 * 1024); // Buffer de 512 KB
    player.setAutoNext(false);

    // Configuración del ecualizador
    audio_tools::Equalizer3Bands eq(kitStream);
    audio_tools::ConfigEqualizer3Bands cfg_eq;
    //audio_tools::ConfigEqualizer3Bands cfg_eq = eq.defaultConfig();
    cfg_eq.gain_low = EQ_LOW;
    cfg_eq.gain_medium = EQ_MID;
    cfg_eq.gain_high = EQ_HIGH;
    eq.addNotifyAudioChange(kitStream);
    eq.begin(cfg_eq);

    // decoder->setOutput(eq);
    // decoder->addNotifyAudioChange(kitStream);
    // decoder->begin();

    if (isWav)
    {
      decoderWAV.addNotifyAudioChange(kitStream);
      //decoderWAV.begin();

      player.setAudioSource(source);
      player.setOutput(eq);
      player.setDecoder(decoderWAV);
      decoderWAV.begin();
    }
    else
    {
      decoderMP3.addNotifyAudioChange(kitStream);
      // decoderMP3.begin();

      player.setAudioSource(source);
      player.setOutput(eq);
      player.setDecoder(metadatafilter);
      decoderMP3.begin();
    }


    // Inicialización del reproductor
    //player.addNotifyAudioChange(decoder);
    if (!player.begin()) {
        logln("Error player initialization");
        STOP = true;
        PLAY = false;
        return;
    }

    // Variables del bucle

    // Esto lo hacemos para capturar el fichero seleccionado
    source.selectStream(PATH_FILE_TO_LOAD.c_str()); // Seleccionamos el archivo actual
    source.setIndex(findIDByLastField(file, FILE_LOAD.c_str()) - 1); // Buscamos el índice del archivo actual

    // Cogemos mas info e inicializamos variables
    size_t fileSize = getStreamfileSize(PATH_FILE_TO_LOAD);
    size_t fileread = 0;
    int bitRateRead = isWav ? decoderWAV.audioInfoEx().byte_rate : decoderMP3.audioInfoEx().bitrate;
    int totalFilesIdx = source.size();
    int currentIdx = source.index(); // El índice actual del archivo
    int stateStreamplayer = 0;
    unsigned long lastUpdate = millis();
    unsigned long twiceRWDTime = millis();
    int last_blockSelected = 0;
    bool was_pressed_wd = false;
    //
    TOTAL_BLOCKS = totalFilesIdx + 1;
    BLOCK_SELECTED = currentIdx + 1; // Para mostrar el bloque seleccionado en la pantalla

    // Esto lo hacemos para coger el sampling rate del PLAYER
    sample_rate_t srd = player.audioInfo().sample_rate;
    hmi.writeString("tape.lblFreq.txt=\"" + String(int(srd/1000)) + "KHz\"" );   
    // Esto lo hacemos para poder abrir el block browser sin haber pulsado PLAY.
    hmi.writeString("tape.BBOK.val=1");
    // Actualización inicial de indicadores
    updateIndicators(totalFilesIdx, source.index() + 1, fileSize, bitRateRead, source.toStr());

    // Bucle principal
    while (!EJECT && !REC) 
    {
        // Actualizamos el volumen y el ecualizador si es necesario
        kitStream.setVolume(MAIN_VOL / 100);
        if (EQ_CHANGE) {
            EQ_CHANGE = false;
            cfg_eq.gain_low = EQ_LOW;
            cfg_eq.gain_medium = EQ_MID;
            cfg_eq.gain_high = EQ_HIGH;
            eq.begin(cfg_eq);
        }
        // Estados del reproductor
        switch (stateStreamplayer) {
            case 0: // Esperando reproducción
                if (PLAY) 
                {
                    player.begin(currentIdx); // Iniciamos el reproductor
                    stateStreamplayer = 1;
                    tapeAnimationON();
                }
                break;

            case 1: // Reproduciendo
                fileread += player.copy();
                if (fileSize > 0) {
                    PROGRESS_BAR_TOTAL_VALUE = (fileread * 100) / fileSize;
                }
 
                // Actualizamos indicadores cada 4 segundos
                if (millis() - lastUpdate > 2000) 
                {
                    updateIndicators(totalFilesIdx, source.index()+1, fileSize, bitRateRead, source.toStr());
                    lastUpdate = millis();
                }

                // Verificamos si se terminó el archivo
                // if (fileread >= fileSize) 
                // {
                //     if (!disable_auto_media_stop)
                //     {
                //       stateStreamplayer = 4; // Auto-stop      
                //     }
                // }

                if (STOP) 
                {
                  stateStreamplayer = 0;
                  fileread = 0;
                  tapeAnimationOFF();
                }    
                
                if (PAUSE) 
                {
                  stateStreamplayer = 2; // Pausa
                  tapeAnimationOFF();
                  PLAY=false;
                  PAUSE=false;
                }  
                break;

            case 2: // PAUSE
                if (PAUSE || PLAY)
                {
                  stateStreamplayer = 1; // Reproduciendo
                  tapeAnimationON();
                  PAUSE = false;
                }
                else if (STOP)
                {
                  stateStreamplayer = 0;
                  fileread = 0;
                  tapeAnimationOFF();
                }
                break;
            
            case 4: // Auto-stop
                tapeAnimationOFF();
                stateStreamplayer = 0;
                PLAY = false;
                STOP = true;
                break;                
            
            default:
                break;
        }

        // Control de avance/retroceso
        if ((FFWIND || RWIND) && !was_pressed_wd) 
        {
            rewindAnimation(FFWIND ? 1 : -1);
            if (FFWIND) 
            {
              player.next();
            } 
            else
            {
              if (millis() - twiceRWDTime > 5000)
              {
                // Empiezo desde el principio
                player.begin(source.index());
                twiceRWDTime = millis();
              }
              else
              {
                // Si pulso rapido en los proximos segundos               
                player.previous();
              }
            }

            // delay(250);
            currentIdx = source.index();
            player.begin(currentIdx);
            delay(250);
            fileSize = getStreamfileSize(source.toStr());

            if (isWav)
            {

              if (decoderWAV.audioInfo().bits_per_sample == 8)
              {
                // Cambiamos el sampling rate a 22KHz para el kitStream
                //                
                hmi.writeString("tape.wavind.txt=\"WAV8\"");
              }
              else
              {
                if (OUT_TO_WAV)
                {
                  hmi.writeString("tape.wavind.txt=\"WAV\"");
                }
                else
                {
                  hmi.writeString("tape.wavind.txt=\"\"");
                }
              }              
            }
       
            // Esto lo hacemos para coger el sampling rate
            sample_rate_t srd = player.audioInfo().sample_rate;
            hmi.writeString("tape.lblFreq.txt=\"" + String(int(srd/1000)) + "KHz\"" );            

            if ((source.index() > (source.size()-1)))
            {
              if(disable_auto_media_stop) 
              {
                source.selectStream(0);
                //source.setIndex(0);
                currentIdx = 0;
                player.begin(); // Reiniciar el reproductor
              } 
              else if (!disable_auto_media_stop && (source.index() > (source.size()-1))) 
              {
                source.selectStream(0);  
                //source.setIndex(0);            
                currentIdx = 0;
                player.begin(); // Reiniciar el reproductor
                player.stop(); // Detener el reproductor
                fileSize = getStreamfileSize(source.toStr());
                STOP=true;
                PLAY=false;
              } 
            }   
            FFWIND = RWIND = false;
            fileread = 0;
            //
            updateIndicators(totalFilesIdx, source.index() + 1, fileSize, bitRateRead, source.toStr());
        }
        else
        {
          was_pressed_wd = false;
          //
          KEEP_FFWIND = false;
          KEEP_RWIND = false;
          //
          FFWIND = false;
          RWIND = false;
        }
   
        if (KEEP_FFWIND || KEEP_RWIND) 
        {
            if (KEEP_FFWIND)
            {
              // Avance rapido
              fileread += player.copy(5 * DEFAULT_BUFFER_SIZE);
            }
            else
            {
              // Retroceso rapido
              if (fileread > (5 * DEFAULT_BUFFER_SIZE))
              {
                fileread = player.copy(fileread - (5 * DEFAULT_BUFFER_SIZE));
              }
            }

            if (fileSize > 0) 
            {
              PROGRESS_BAR_TOTAL_VALUE = (fileread * 100) / fileSize;
            }
            //
            // Esto se usa para evitar entrar en FFWD o RWD despues de una pulsacion prolongada (y soltar)
            was_pressed_wd = true;
         }
        // Seleccion de pista
        if (UPDATE)
        {
          // Si el bloque seleccionado es válido y no es el último
          if (BLOCK_SELECTED > 0 && (BLOCK_SELECTED <= (totalFilesIdx+1))) {
              // Reproducir el bloque seleccionado
              //source.selectStream((FILE_LAST_DIR + findLastFieldByID(file,BLOCK_SELECTED)).c_str());
              source.setIndex(BLOCK_SELECTED); // Buscamos el índice del archivo actual
              currentIdx = source.index() - 1; // Buscamos el índice del archivo actual
          } else {
              // Reproducir desde el principio
              currentIdx = 0;
              source.selectStream(0);
          }  
          // Actualizamos de manera inmediata
          //

          player.begin(currentIdx); // Iniciamos el reproductor      
          delay(250);
            
          fileSize = getStreamfileSize(source.toStr());

          // Esto lo hacemos para coger el sampling rate
          sample_rate_t srd = player.audioInfo().sample_rate;
          hmi.writeString("tape.lblFreq.txt=\"" + String(int(srd/1000)) + "KHz\"" );    
          bitRateRead = isWav ? decoderWAV.audioInfoEx().byte_rate : decoderMP3.audioInfoEx().bitrate;
          updateIndicators(totalFilesIdx, source.index() + 1, fileSize, bitRateRead, source.toStr());  
          //                
          UPDATE = false;                
        }

        if (BB_OPEN || BB_UPDATE)
        {
          last_blockSelected = BLOCK_SELECTED;
          //
          hmi.openBlockMediaBrowser(source);
          //delay(25);
          hmi.openBlockMediaBrowser(source);
          BB_OPEN = false;
          BB_UPDATE = false; 
        }

        if (UPDATE_HMI)
        {
          if (BLOCK_SELECTED > 0 && BLOCK_SELECTED <= TOTAL_BLOCKS)
          {
              // Actualizamos la pantalla HMI con el nombre del archivo actual
              //source.selectStream((FILE_LAST_DIR + myMediaDescriptor[BLOCK_SELECTED-1].name).c_str());
              // Cogemos el indice que empieza desde 0 ..
              source.setIndex(BLOCK_SELECTED - 1); // Buscamos el índice del archivo actual
              currentIdx = source.index();

              // logln("Update HMI");
              // logln("------------------------------");
              // logln("Block selected: " + String(BLOCK_SELECTED));
              // logln("source index: " + String(source.index()));

              // Inicializamos el player con ese indice
              player.begin(currentIdx); // Iniciamos el reproductor

              // Cogemos informacion del fichero
              delay(250);
              fileSize = getStreamfileSize(source.toStr());
              
              // Esto lo hacemos para coger el sampling rate
              sample_rate_t srd = player.audioInfo().sample_rate;
              hmi.writeString("tape.lblFreq.txt=\"" + String(int(srd/1000)) + "KHz\"" );                         
              // Actualizamos HMI
              updateIndicators(totalFilesIdx, source.index()+1, fileSize, bitRateRead, source.toStr());  

              #ifdef DEBUGMODE
                  logln("Update HMI: " + String(BLOCK_SELECTED) + " - " + String(totalFilesIdx));
                  logln("Current IDX: " + String(currentIdx));
                  logln("Current file: " + String(source.toStr()));
                  logln("Current file size: " + String(fileSize) + " bytes");
                  logln("Current file bitrate: " + String(bitRateRead) + " bps");
                  logln("Current file index: " + String(source.index()));
                  logln("Current file name: " + String(myMediaDescriptor[BLOCK_SELECTED-1].name));
                  logln("Current file path: " + String(myMediaDescriptor[BLOCK_SELECTED-1].path));
                  logln("Current file ID: " + String(myMediaDescriptor[BLOCK_SELECTED-1].ID));
              #endif                    
          }
          else
          {
            BLOCK_SELECTED = last_blockSelected;
          }

          UPDATE_HMI = false;
        }        
   
   }

    // Finalización
    tapeAnimationOFF();
    player.end();
    eq.end();
    //decoder->end();
    decoderMP3.end();
    decoderWAV.end(); 
    source.end();
    file.close();
}
You must be logged in to vote
5 replies
@pschatzmann
Comment options

This is the worst spaghetti method that I have ever seen in my life!

  • Use classes with methods to structure the problem properly
  • If you want to get the actual audio information (e.g. to diplay it in a gui) you can sublass this class from AudioInfoSupport
  • If you want to extend the functionality of the player: why not create your own subclass with additional methods ?
  • If you have multiple decoders: use the MultiDecoder
  • Prefer passing the objects in the constructor instead of setter methods: this prevents you from running into sequence issues
  • Please provide the most simple test sketch with the corresponding wav file to reproduce the issue and show the log (with level info)
  • your data flow seems to be messed up and you seem to be undecided what the output for the player should be!
  • Don't invent your own status variables, but ask the player for the status
@pschatzmann
Comment options

I have given you some valuable advice how to structure your solution properly, so please take this seriously.
You have the opportunity to improve!

@hash6iron
Comment options

My media player is not an isolated method. I put all into a method because is the only way to achieve that mp3 and WAV processing with good sound quality, without micro-breaks and others problems that I have experimented. This player is a small part of my project, then I only need that this method works fine, this means, the sampling rate will be transmitted to the output correctly.

Player has defined what's the output, the equalizer and this last, audiokitstream.

Where are you seeing several possible outputs?

On the other hand, all your examples are very basic, then is not possible to achieve a good result because the library is very big and wiki and basic examples only help for a toy projects.

@pschatzmann
Comment options

No, there can be only one output (with the exception of the MultiOutput class).
You need to build a chain: The player outputs to the Equilizer and you need to tell the Equilizer to output to audiokitstream.

Here is the inconsistent code:

player.setOutput(kitStream);
player.setOutput(eq);

I'm not sure where your performance issues are coming from: this might be worth to have a more detailed look.

@hash6iron
Comment options

I had the coded structured, but I saw that puting all in, was the best solution, anyway the goal is play mp3 or WAV files, then "if works not touch anymore".

I'm going to review some of your recommendations.

Thanks for all.

Comment options

@pschatzmann Where Can I found examples with AudioInfoSupport?

You must be logged in to vote
0 replies
Comment options

In the class documentation

You must be logged in to vote
0 replies
Comment options

@pschatzmann

Why this below doesn't work with WAV? I'm monitoring that AudioKitStream is set to 22KHz and decoder at 44.1KHz, with MP3 all is OK and after these lines below, AudioKitStream put output at 44.1KHz, why with WAV not?

decoder is a MultiDecoder.
kitStream is AudioBoardStream

    // Actualizamos el sampling rate del kitStream
    AudioInfo info = kitStream.defaultConfig();
    info.sample_rate = decoder.audioInfo().sample_rate;
    kitStream.setAudioInfo(info);
You must be logged in to vote
0 replies
Comment options

Ok. I already know the problem. Is not the sampling rate is the bits per sample. How I do to plays correctly with AudioPlayer a 8-bit WAV?

You must be logged in to vote
1 reply
@pschatzmann
Comment options

You need to add a number format converter to your chain. 8 bit wav is using uint8_t!

Comment options

Ok, I understand but. How Can I convert conditionated to the bit_per_sample of the file to be played?

You must be logged in to vote
1 reply
@pschatzmann
Comment options

By defining the output of the player based on the bit_per_sample: The cleanest way would be really to have your separarate sublass of AudioInfoSupport and in your setAudioInfo() implementation you can do this based on the provided information.
You can have your class notifed by calling player.addNotifiyAudioChange(your_object).

By having your own class you can also split up your huge method into smaller logical pices

Comment options

One doubt. Who has the information of sampling rate of the source file (wav, mp3, etc) decoder? player? I've saw that a 8-bit and 22KHz wav sample if I get sampling rate info from decoder is not correct.

You must be logged in to vote
1 reply
@pschatzmann
Comment options

The player gets notified from the decoder and based on this notifies it's output.

There is another alternative chain where you could add an EncodedAudioStream to your output chain and you dynamically switch the decoder based on the bits_per_sample:

  • CopyDecoder for no change
  • DecoderL8 for 8 bit

This has the advantage that you have a conistent output chain.

Comment options

Ok. I see that in the wav file header that I'm using for testing

image

If you observe, the native sampling rate is 22KHz. Well, when I ask to decoder and player, both say me that file is at 44.1KHz. Why?

logln("Source sampling rate: " + String(decoder.audioInfo().sample_rate));

You must be logged in to vote
1 reply
@pschatzmann
Comment options

You see the default value! The value from the decoder is only updated after you started to play the audio.
The decoder needs to have the data from the source to privde the actual information ...

You could call a single copy to update the info for wav, but for mp3 a single copy might not be sufficient though...

Comment options

Ok. sampling rate issue solved. But I don't achieve to solve the transformation to different bits_per_sample. The player freezes when I try to convert.

Then the chain is that below.

source -> decoder -> player -> eq -> EncodedAudioStream -> Transformation -> AudioBoardStrem out.

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
🙏
Q&A
Labels
None yet
2 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.