Thanks a lot for explaination.
BR,
Lorenzo.
VSIDE development for VS1053B
-
- Senior User
- Posts: 75
- Joined: Mon 2021-03-01 23:01
Re: VSIDE development for VS1053B
Hi Pasi.
Thanks a lot for answers.
Specifically, I started from the template decimator for the VS1053 by slightly modifying the code in order to obtain a decimation of the samples from 48k to 8k, just to do a test.
The code used for the plugin is the following:
Disable();
InitAudioExample(48000U/*input samplerate*/,1/*use line-in instead of mic-in*/,CORE_CLOCK_2X);
SetHardware(2/*stereo output*/, OUTPUT_SAMPLERATE/*DA sample rate*/);
USEX(INT_ENABLE) |= (1<<INT_EN_MODU)/*AD*/ | (1<<INT_EN_DAC);
audio_rd_pointer = audio_buffer;
audio_wr_pointer = audio_buffer + MY_DECIM_FACTOR*2*2;
memsetY(audio_buffer, 0, AUDIO_BUFFER_SZ);
Enable();
while (1) {
if (StreamDiff() >= 2*MY_DECIM_FACTOR) {
__y s_int16 *delayLinePtr = lineInPtr;
int i;
for (i=0;i<MY_DECIM_FACTOR;i++) {
lineInPtr += 2;
if (lineInPtr >= lineInBuf + LINE_IN_BUF_LEN*2) {
lineInPtr -= LINE_IN_BUF_LEN*2;
}
StreamBufferReadData(lineInPtr, 2);
}
audioOut[0] = lineInPtr[0]; // left channel
audioOut[1] = lineInPtr[1]; // right channel
AudioOutputSamples(audioOut, 1);
}
}
MCU side, the code SPI is instead the following:
write_register(device, SCI_CLOCKF, 0xC000);
while (!audioCodecReadyForData(device));
write_register(device, SCI_WRAMADDR, INT_ENABLE);
write_register(device, SCI_WRAM, 0x02);
write_register(device, SCI_AICTRL0, 16000U);
write_register(device, SCI_AICTRL1, 1024);
write_register(device, SCI_AICTRL2, 0);
write_register(device, SCI_AICTRL3, 4);
write_register(device, SCI_MODE, SM_ADPCM | SM_SDINEW);
loadPCMPluginLorenzo(device);
write_register(device, SCI_AIADDR, 0x50);
vTaskDelay(1/portTICK_PERIOD_MS);
while (!readyForData(device));
Unfortunately, however, using this plugin I modified, the loadPCMPluginLorenzo never end.
Attached plugin code.
Could you please give me indication about how to make it working?
Thanks a lot for answers.
Specifically, I started from the template decimator for the VS1053 by slightly modifying the code in order to obtain a decimation of the samples from 48k to 8k, just to do a test.
The code used for the plugin is the following:
Disable();
InitAudioExample(48000U/*input samplerate*/,1/*use line-in instead of mic-in*/,CORE_CLOCK_2X);
SetHardware(2/*stereo output*/, OUTPUT_SAMPLERATE/*DA sample rate*/);
USEX(INT_ENABLE) |= (1<<INT_EN_MODU)/*AD*/ | (1<<INT_EN_DAC);
audio_rd_pointer = audio_buffer;
audio_wr_pointer = audio_buffer + MY_DECIM_FACTOR*2*2;
memsetY(audio_buffer, 0, AUDIO_BUFFER_SZ);
Enable();
while (1) {
if (StreamDiff() >= 2*MY_DECIM_FACTOR) {
__y s_int16 *delayLinePtr = lineInPtr;
int i;
for (i=0;i<MY_DECIM_FACTOR;i++) {
lineInPtr += 2;
if (lineInPtr >= lineInBuf + LINE_IN_BUF_LEN*2) {
lineInPtr -= LINE_IN_BUF_LEN*2;
}
StreamBufferReadData(lineInPtr, 2);
}
audioOut[0] = lineInPtr[0]; // left channel
audioOut[1] = lineInPtr[1]; // right channel
AudioOutputSamples(audioOut, 1);
}
}
MCU side, the code SPI is instead the following:
write_register(device, SCI_CLOCKF, 0xC000);
while (!audioCodecReadyForData(device));
write_register(device, SCI_WRAMADDR, INT_ENABLE);
write_register(device, SCI_WRAM, 0x02);
write_register(device, SCI_AICTRL0, 16000U);
write_register(device, SCI_AICTRL1, 1024);
write_register(device, SCI_AICTRL2, 0);
write_register(device, SCI_AICTRL3, 4);
write_register(device, SCI_MODE, SM_ADPCM | SM_SDINEW);
loadPCMPluginLorenzo(device);
write_register(device, SCI_AIADDR, 0x50);
vTaskDelay(1/portTICK_PERIOD_MS);
while (!readyForData(device));
Unfortunately, however, using this plugin I modified, the loadPCMPluginLorenzo never end.
Attached plugin code.
Could you please give me indication about how to make it working?
- Attachments
-
- MyProject.plg
- (8.57 KiB) Downloaded 210 times
-
- Senior User
- Posts: 75
- Joined: Mon 2021-03-01 23:01
-
- Senior User
- Posts: 75
- Joined: Mon 2021-03-01 23:01
Re: VSIDE development for VS1053B
Hi,
I have a VS1053B controlled through SPI interface by a MCU. Thus, I'm using the audio codec as a slave.
I'm trying to develop a plugin which is able to register audio samples PCM stereo (24kHz) with VOX detection capability signalled through the GPIO4.
Below I have indicated part of the code that I used both on the MCU side and for the plugin.
The problem I encountered is that after loading the plugin, the HDAT1 register always contains zero words.
Could you please help me understand what I'm doing wrong?
Attached I have reported the entire project of a test plugin that I have prepared.
Thanks a lot for any suggestions.
BR,
Lorenzo.
MCU Side
write_register(device, SCI_MODE, 0x5800 /*SM_ADPCM | SM_SDINEW*/);
write_register(device, SCI_AICTRL0, 24000U);
write_register(device, SCI_AICTRL1, 1024);
write_register(device, SCI_AICTRL2, 0);
write_register(device, SCI_AICTRL3, 0);
write_register(device, SCI_AIADDR, 0x50);
while (!readyForData(DREQ));
Plugin
// Enable interrupts
Enable();
Enable();
while (1)
{
// Wait until there is enough audio data to process
// StreamDiff() - Tells how many 16-bit words (samples) there are in the stream buffer.
if (StreamDiff() > BLOCKSIZE*2)
{
// Read input samples (stereo, hence 2 x block size)
StreamBufferReadData(lineInBuf, 2*BLOCKSIZE);
// Copy line-in to auxiliary buffer (From Y-memory to X-memory)
for(i=0; i < BLOCKSIZE*2; i++)
{
*outputBufPtr++ = *lineInPtr++;
}
// Ouput sample pairs
AudioOutputSamples(outputBuf, BLOCKSIZE);
}
}
I have a VS1053B controlled through SPI interface by a MCU. Thus, I'm using the audio codec as a slave.
I'm trying to develop a plugin which is able to register audio samples PCM stereo (24kHz) with VOX detection capability signalled through the GPIO4.
Below I have indicated part of the code that I used both on the MCU side and for the plugin.
The problem I encountered is that after loading the plugin, the HDAT1 register always contains zero words.
Could you please help me understand what I'm doing wrong?
Attached I have reported the entire project of a test plugin that I have prepared.
Thanks a lot for any suggestions.
BR,
Lorenzo.
MCU Side
write_register(device, SCI_MODE, 0x5800 /*SM_ADPCM | SM_SDINEW*/);
write_register(device, SCI_AICTRL0, 24000U);
write_register(device, SCI_AICTRL1, 1024);
write_register(device, SCI_AICTRL2, 0);
write_register(device, SCI_AICTRL3, 0);
write_register(device, SCI_AIADDR, 0x50);
while (!readyForData(DREQ));
Plugin
// Enable interrupts
Enable();
Enable();
while (1)
{
// Wait until there is enough audio data to process
// StreamDiff() - Tells how many 16-bit words (samples) there are in the stream buffer.
if (StreamDiff() > BLOCKSIZE*2)
{
// Read input samples (stereo, hence 2 x block size)
StreamBufferReadData(lineInBuf, 2*BLOCKSIZE);
// Copy line-in to auxiliary buffer (From Y-memory to X-memory)
for(i=0; i < BLOCKSIZE*2; i++)
{
*outputBufPtr++ = *lineInPtr++;
}
// Ouput sample pairs
AudioOutputSamples(outputBuf, BLOCKSIZE);
}
}
- Attachments
-
- Passthrough.zip
- Plugin solution
- (8.62 KiB) Downloaded 227 times
-
- Senior User
- Posts: 75
- Joined: Mon 2021-03-01 23:01
Re: VSIDE development for VS1053B
I tried to better understand why this behaviour.
What I noted is that adding a LED on GPIO4 with:
GPIO_SET_LOW(GPIO4);
if (StreamDiff() > BLOCKSIZE*2)
{
// Read input samples (stereo, hence 2 x block size)
StreamBufferReadData(lineInBuf, 2*BLOCKSIZE);
// Switch on LED
GPIO_SET_HIGH(GPIO4);
the LED switches on.
This means the problem is not ADC, StreamDiff() is major than BLOCKSIZE*2.
The main question is related to the AudioOutputSamples functions.
I read that AudioOutputSamples is used to send data to the DAC.
But I think, in my case, the DAC shouldn't be necessary because I'm reading encoded data through digital interface SPI.
Are my considerations right?
Thanks a lot.
Lorenzo.
What I noted is that adding a LED on GPIO4 with:
GPIO_SET_LOW(GPIO4);
if (StreamDiff() > BLOCKSIZE*2)
{
// Read input samples (stereo, hence 2 x block size)
StreamBufferReadData(lineInBuf, 2*BLOCKSIZE);
// Switch on LED
GPIO_SET_HIGH(GPIO4);
the LED switches on.
This means the problem is not ADC, StreamDiff() is major than BLOCKSIZE*2.
The main question is related to the AudioOutputSamples functions.
I read that AudioOutputSamples is used to send data to the DAC.
But I think, in my case, the DAC shouldn't be necessary because I'm reading encoded data through digital interface SPI.
Are my considerations right?
Thanks a lot.
Lorenzo.
-
- Senior User
- Posts: 75
- Joined: Mon 2021-03-01 23:01
Re: VSIDE development for VS1053B
Hi,
waiting for a sensible answer, I made another test to confirm what I was thinking (following the suggestion of @Henrik in this topic viewtopic.php?f=11&t=586&p=9466&hilit=o ... +SPI#p9466)
My plugin has been modified in order to be as the following, in order to increment by 1 the SCI_VOL each 10k loop cycles.
while (1)
{
if(times == 10000)
{
counter++;
times = 0;
}
else
times++;
if(counter > 255)
counter = 1;
// Wait until there is enough audio data to process
if (StreamDiff() > BLOCKSIZE*2)
{
// Read input samples (stereo, hence 2 x block size)
StreamBufferReadData(lineInBuf, 2*BLOCKSIZE);
// Copy line-in to auxiliary buffer (From Y-memory to X-memory)
memcpyYX(outputBuf, lineInBuf, 2*BLOCKSIZE);
USEX(SCI_VOL) = counter;
AudioOutputSamples(outputBuf, BLOCKSIZE);
}
.....
In MCU code, I wrote:
BEFORE LOAD PLUGIN
uint16_t volume = read_register(codec, SCI_VOL);
ESP_LOGI(VS1053_TAG, "VOLUME=%d", volume);
With this result:
I (589) VS1053: VOLUME=0
AFTER LOAD PLUGIN
uint16_t rate = read_register(device, SCI_AICTRL0);
uint16_t gain = read_register(device, SCI_AICTRL1);
uint16_t volume = read_register(device, SCI_VOL);
ESP_LOGI("Driver Custom", "Volume=%d, Rate=%d, Gain=%d", volume, rate, gain);
With the following result:
I (749) ENCENGINE: Sample=3, Rate=24000, Gain=1024
I (749) ENCENGINE: Sample=4, Rate=24000, Gain=1024
I (759) ENCENGINE: Sample=5, Rate=24000, Gain=1024
I (759) ENCENGINE: Sample=6, Rate=24000, Gain=1024
I (769) ENCENGINE: Sample=6, Rate=24000, Gain=1024
I (769) ENCENGINE: Sample=7, Rate=24000, Gain=1024
I (779) ENCENGINE: Sample=8, Rate=24000, Gain=1024
....
I (2179) ENCENGINE: Sample=252, Rate=24000, Gain=1024
I (2179) ENCENGINE: Sample=253, Rate=24000, Gain=1024
I (2189) ENCENGINE: Sample=254, Rate=24000, Gain=1024
I (2189) ENCENGINE: Sample=255, Rate=24000, Gain=1024 <-- Rollout of counter variable in my code.
I (2199) ENCENGINE: Sample=1, Rate=24000, Gain=1024
I (2199) ENCENGINE: Sample=2, Rate=24000, Gain=1024
I (2209) ENCENGINE: Sample=3, Rate=24000, Gain=1024
I (2219) ENCENGINE: Sample=4, Rate=24000, Gain=1024
I (2229) ENCENGINE: Sample=5, Rate=24000, Gain=1024
This means that my plugin is working and samples from ADC are taken in block of 2*BLOCKSIZE.
But in output the HDAT1 register is always ZERO.
I still insist:
Is this call AudioOutputSamples(outputBuf, BLOCKSIZE); also valid for SPI output in HDAT0/HDAT1??
In my case, I really need to use DAC (in your forum I read that AudioOutputSamples is used to writing for DAC).
Please, could I receive an answer in order to continue using the VLSI products I bought?
Attached the screenshot of my result MCU side.
waiting for a sensible answer, I made another test to confirm what I was thinking (following the suggestion of @Henrik in this topic viewtopic.php?f=11&t=586&p=9466&hilit=o ... +SPI#p9466)
My plugin has been modified in order to be as the following, in order to increment by 1 the SCI_VOL each 10k loop cycles.
while (1)
{
if(times == 10000)
{
counter++;
times = 0;
}
else
times++;
if(counter > 255)
counter = 1;
// Wait until there is enough audio data to process
if (StreamDiff() > BLOCKSIZE*2)
{
// Read input samples (stereo, hence 2 x block size)
StreamBufferReadData(lineInBuf, 2*BLOCKSIZE);
// Copy line-in to auxiliary buffer (From Y-memory to X-memory)
memcpyYX(outputBuf, lineInBuf, 2*BLOCKSIZE);
USEX(SCI_VOL) = counter;
AudioOutputSamples(outputBuf, BLOCKSIZE);
}
.....
In MCU code, I wrote:
BEFORE LOAD PLUGIN
uint16_t volume = read_register(codec, SCI_VOL);
ESP_LOGI(VS1053_TAG, "VOLUME=%d", volume);
With this result:
I (589) VS1053: VOLUME=0
AFTER LOAD PLUGIN
uint16_t rate = read_register(device, SCI_AICTRL0);
uint16_t gain = read_register(device, SCI_AICTRL1);
uint16_t volume = read_register(device, SCI_VOL);
ESP_LOGI("Driver Custom", "Volume=%d, Rate=%d, Gain=%d", volume, rate, gain);
With the following result:
I (749) ENCENGINE: Sample=3, Rate=24000, Gain=1024
I (749) ENCENGINE: Sample=4, Rate=24000, Gain=1024
I (759) ENCENGINE: Sample=5, Rate=24000, Gain=1024
I (759) ENCENGINE: Sample=6, Rate=24000, Gain=1024
I (769) ENCENGINE: Sample=6, Rate=24000, Gain=1024
I (769) ENCENGINE: Sample=7, Rate=24000, Gain=1024
I (779) ENCENGINE: Sample=8, Rate=24000, Gain=1024
....
I (2179) ENCENGINE: Sample=252, Rate=24000, Gain=1024
I (2179) ENCENGINE: Sample=253, Rate=24000, Gain=1024
I (2189) ENCENGINE: Sample=254, Rate=24000, Gain=1024
I (2189) ENCENGINE: Sample=255, Rate=24000, Gain=1024 <-- Rollout of counter variable in my code.
I (2199) ENCENGINE: Sample=1, Rate=24000, Gain=1024
I (2199) ENCENGINE: Sample=2, Rate=24000, Gain=1024
I (2209) ENCENGINE: Sample=3, Rate=24000, Gain=1024
I (2219) ENCENGINE: Sample=4, Rate=24000, Gain=1024
I (2229) ENCENGINE: Sample=5, Rate=24000, Gain=1024
This means that my plugin is working and samples from ADC are taken in block of 2*BLOCKSIZE.
But in output the HDAT1 register is always ZERO.
I still insist:
Is this call AudioOutputSamples(outputBuf, BLOCKSIZE); also valid for SPI output in HDAT0/HDAT1??
In my case, I really need to use DAC (in your forum I read that AudioOutputSamples is used to writing for DAC).
Please, could I receive an answer in order to continue using the VLSI products I bought?
Attached the screenshot of my result MCU side.
- Attachments
-
- Immagine.png (73.81 KiB) Viewed 3106 times
-
- Senior User
- Posts: 75
- Joined: Mon 2021-03-01 23:01
Re: VSIDE development for VS1053B
For this post, @Pasi provides a great answer and explaination here:
viewtopic.php?f=7&t=2941&p=15196#p15196
Thanks a lot, Pasi.
BR
Lorenzo.
viewtopic.php?f=7&t=2941&p=15196#p15196
Thanks a lot, Pasi.
BR
Lorenzo.