Program a Plugin for VS1053

Installing and using VSIDE tools for VLSI Solution's devices that contain a VSDSP signal processor.
Post Reply
Daniel S.
User
Posts: 3
Joined: Fri 2023-09-15 10:02

Program a Plugin for VS1053

Post by Daniel S. »

Hi support,

I build a application like:

MP3 File-> SD Card -> Arduino -> Audio PlugIn from VSide-> SCI Interface -> VS1053 -> StreamBufferReadData() -> memcpyYX -> AudioOutputSamples() -> Output on LOUT Speaker

So the Plugin and all stuff works but the output signal is very very noisy and it seems that the input signal cannot read right from StreamBufferReadData(). If I listen without a loaded plugin audio signal is how expected.

OS: Win10 64bit
Arduino Uno R3 witth IDE V2.0.2
VS1053: https://www.adafruit.com/product/1381
VSIDE 2.48 Example project: Audio Effects linked as plugin


Here is the source...I only changed that it twice Enable() and USE_SIMPLE_DSP_BOARD;

Code: Select all

/* For free support for VSIDE, please visit www.vsdsp-forum.com */

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Audio effect example for VS1053/VS1063
//
// Flanger, chorus and delay with adjustable parameters
// (see "effect.h" for the parameters)
//
// press button on board to bypass effect when program is running
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#define USE_SIMPLE_DSP_BOARD
//#define USE_PROTOTYPING_BOARD
// (define *one* of the PCB types before including board.h)
#include "board.h"

#define USE_MIC 0 // define 1 for mic-in, 0 for line-in

#include <string.h>
#include <stdlib.h>
#include "effect.h"

void InitAudioExample(u_int16 srInput,int useMicIn,u_int16 coreClock); // (see "init.c")

static s_int16 __y delayBuffer[DELAY_BUF_SZ]; // delay line (buffer in Y memory)

main(void) {
	s_int16 auxBuffer[2*BLOCKSIZE]; // auxiliary audio buffer
	s_int16 __y lineInBuf[2*BLOCKSIZE]; // line-in audio buffer
	s_int16 __y *bufptr = delayBuffer;
	s_int16 __y *flgptr = delayBuffer;
	s_int16 phase = 0; // this is the (accumulator) phase for the LFO
	s_int16 flangerSample = 0;
	u_int16 flangerPhase = 0;
	// parameters for the currently selected effect:
	struct Effect effect = {DEPTH, SPEED, DELAY, DECAY, MIX, MIX};
	//
	effect.delay += (effect.depth/2)+1;
	// initialize delay line with silence
	memsetY(delayBuffer, 0, DELAY_BUF_SZ);
	// disable interrupts during initialization
	Disable();
	// basic initialization phase
	InitAudioExample(MY_SAMPLERATE,USE_MIC,CORE_CLOCK_3X);
	// adjust output samplerate
	SetHardware(2/*stereo output*/,MY_SAMPLERATE/*DA sample rate*/);
	//
	USEX(INT_ENABLE)|=(1<<INT_EN_MODU)/*AD*/|(1<<INT_EN_DAC);
	// initialize audio_buffer read and write pointers
#ifdef VS1063
	audioPtr.rd = audio_buffer;
	audioPtr.wr = audio_buffer + 2*BLOCKSIZE;
#else
	audio_rd_pointer = audio_buffer;
	audio_wr_pointer = audio_buffer + 2*BLOCKSIZE;
#endif
	// clear audio buffer (avoid unwanted noise in the beginning)
	memsetY(audio_buffer,0,AUDIO_BUFFER_SZ);
	// set up GPIO
	CONFIGURE_LED_1;
	CONFIGURE_BUTTON_1;
	// set max volume
	USEX(SCI_VOL) = 0x0101;
	// enable interrupts
	Enable();	
	Enable();	
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Main loop
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
	while (1) {
		//
		// wait until there is enough audio data to process
		//
		if (StreamDiff() > BLOCKSIZE*2) {
			u_int16 i;
			s_int16 temp = 0;
			u_int32 fractDelay;
			__y s_int16 *lp = lineInBuf;
			s_int16 *sp = auxBuffer;
			//
			// read input samples (stereo, hence 2 x block size)
			//
			StreamBufferReadData(lineInBuf, 2*BLOCKSIZE);
			//
			if(BUTTON_1_PRESSED) {
				effect.mix=0;
				SET_LED_1_OFF;
			} else {
				effect.mix = effect.mixOrg;
				SET_LED_1_ON;
			}
			//
			// process BLOCKSIZE samples at one go
			//
			for(i=0;i<BLOCKSIZE;i++) {
				// fractional delay part
				s_int16 flangerOut = (s_int16)(((s_int32)*flgptr * (65535U-flangerPhase)) >> 16);
				//
				// advance flgptr (and wrap the cyclic buffer)
				//
				if (flgptr >= delayBuffer+DELAY_BUF_SZ-1) {
					flgptr = delayBuffer;
				} else {
					flgptr++;
				}
				//
				flangerOut += (s_int16)(((s_int32)*flgptr * flangerPhase) >> 16);
				//
				// add input sample to buffer with feedback (decay)
				// mix dry and effect and send to output (mix)
				//
				*sp = (s_int16)(((s_int32)lp[0] * (32000U-effect.mix) + 
						(s_int32)flangerOut * effect.mix) >> 15);
				*bufptr = (s_int16)(((s_int32)*sp++ * effect.decay + 
						(s_int32)lp[0] * (32000U-effect.decay)) >> 15);
				lp += 2;
				sp[0] = sp[-1]; // duplicate output to both channels
				sp++;
				//
				// advance bufptr (and wrap the cyclic buffer)
				//
				if (bufptr	>= delayBuffer+DELAY_BUF_SZ-1) {
					bufptr = delayBuffer;
				} else {
					bufptr++;
				}
			}
			//
			// LFO (speed & depth)
			//
			phase += effect.speed; 
			//
			// LFO value varies from 0 to 1024 (depth = max 2048)
			{
			u_int32 tt = (u_int32)((u_int16)abs(phase)) * effect.depth;
			flangerSample = (u_int16)(tt >> 16);
			flangerPhase = (u_int16)tt;
			}
			//
			// flanger delay
			//
			flgptr = bufptr + flangerSample - effect.delay;
			if (flgptr < delayBuffer) {
				flgptr += DELAY_BUF_SZ;
			}
			//
			// ouput sample pairs
			//
			AudioOutputSamples(auxBuffer, BLOCKSIZE);

		} else { // StreamDiff() <= BLOCKSIZE*2
			//
			// limit values
			//
			if (effect.depth > 2048) {
				effect.depth = 2048;
			}
			if (effect.speed > 1024) {
				effect.speed = 1024;
			}
			if (effect.mix > 32000) {
				effect.mix = 32000;
			}
			if (effect.decay > 32000) {
				effect.decay = 32000;
			}
		} 
	}
	return 0;
}
User avatar
pasi
VLSI Staff
Posts: 2162
Joined: Thu 2010-07-15 16:04

Re: Program a Plugin for VS1053

Post by pasi »

How are you connecting the microphone?

To enable the microphone amplifier, you need to have #define USE_MIC 1, so that InitAudioExample() knows to enable the mic amplifier (0 sets line input, 1 sets mic input).
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook
Daniel S.
User
Posts: 3
Joined: Fri 2023-09-15 10:02

Re: Program a Plugin for VS1053

Post by Daniel S. »

Hi Pasi,

why should I activate the micro, my input is a MP3 file, so I think line-in is the right selection?

But I changed to use_mic=1...no change, noise is the same.
Hannu
VLSI Staff
Posts: 546
Joined: Mon 2016-05-30 11:54
Location: Finland
Contact:

Re: Program a Plugin for VS1053

Post by Hannu »

I'm not an VS1053 expert, Pasi is, but I read your code.

How big the BLOCKSIZE is? You are reserving LineInBuf and auxBuffer from stack. Maybe declaring it in global scope or adding static qualifier to it helps. Chances are that you are going out of stack space.

And as usual try to bisect the problem. Start with simple read input, write output, if it works add something simple as an effect which proves your bufferpointers working correctly. If' simplest loopback doesn't work, you have loading problem or memory access problem or something I didn't guess.
User avatar
pasi
VLSI Staff
Posts: 2162
Joined: Thu 2010-07-15 16:04

Re: Program a Plugin for VS1053

Post by pasi »

I don't understand something. What does the mp3 file have to do with this?

If you want for vs1053b to decode the mp3 file, you just send the file contents to the serial data interface (SDI) in the normal decoding mode. There is no need for any plugins.

The audio effects plugin doesn't perform audio decoding. It gets input from the analog audio input and plays the result at the analog output. You need a different plugin if you want to perform effects on the decoded data (using the "application address hook").
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook
Daniel S.
User
Posts: 3
Joined: Fri 2023-09-15 10:02

Re: Program a Plugin for VS1053

Post by Daniel S. »

If I understand that right, the decoded MP3 file goes directly to the output and it is not possible with this example to read in VSide the decoded MP3 and modify these samples?

analog audio input == IN_MIC
or
analog audio input == lineIn

analog audio input (is not) decoded MP3

My aim was to decode the MP3 File -> modify with echo(or else) -> and output to speaker ... how can I realise that, are there examples?
User avatar
pasi
VLSI Staff
Posts: 2162
Joined: Thu 2010-07-15 16:04

Re: Program a Plugin for VS1053

Post by pasi »

You need to "hook" into a function that is called before the decoded samples are put into the DAC output buffer. This is the application hook, set by the AIADDR register.

There doesn't seem to be any "application hook" plugins in VSIDE templates. There are a few older example packages that use the command-line tools and Makefile (run make to build). Would you be able to work with this?

http://www.vlsi.fi/fileadmin/software/V ... tmf050.zip (this has a vs1053 version too, and a short document about plugins)

If you also want to use the vs1053b patches package, then you need to change the memory allocation to avoid clashes.
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook
Post Reply