The NUC505 DPS Sample Project

The Bongiovi DPS SDK Sample Project for the Nuvoton ARM Processors contains everything you need to get started.  It is pre-configured to allow easy adjustment of:

  • 44.1kHZ or 48kHz sample rate
  • Analog or IIS slave input/output
  • Analog ADC/DAC gain levels
  • 16 or 32 bit PCM audio to floating point samples conversion

Instructions below are for the NUC505 platform:

NUC505 BSP and DPS Project setup

This project is set up for the Keil ARM IDE using the Nuvoton NUC505 Board Support Package (BSP) version 3.00.003.  The Bongiovi DPS Keil project folder must be placed next to the BSP folder in your working directory.

  • NUC505BSPV3.00.003  <– Root folder of the BSP
    • Document  <– Full documentation for the BSP is in here.
    • Library
    • Third Party
    • Sample Code
  • BGV_MIC or BGV_SPEAKER <– Place the Bongiovi DPS Sample project next to the BSP folder
    • This is the Bogniovi SDK project folder.
    • Place indices.c file here.
    • This folder also includes DPSlib, nuc505_isr.c and main.c.
      • KEIL
        • Main Project.uvproj project file is here.  Double-click the .uvproj file to launch Keil and open the Bongiovi DPS SDK project.
          • obj
            • The compiled Main Project.bin file is generated here.  This is the file that will be flashed into the NUC505 using Keil in ICE mode or the Nu-Link ICP programming tool.

NOTE:  This information is for basic usage of the DPS Sample Project.  For more details about the functions and parameters for the NUC505 BSP refer to the NuMicro NUC505 Series Driver Reference Guide in /BSP Root Folder/Document.

Bongiovi DPS Sample Project Components

NOTE:  Exact line numbers are subject to change in future version.  All line numbers are preceded with ~ to show they are approximate.

DPSlib.lib

This is the compiled DPS processing library.

DPSlib.h

This is the header file for DPSlib.lib.  It contains compiler directives for easy setup of the NUC505 Audio board:

#define MAX_BUFF_LEN     512

This sets the buffer size in frames (number of stereo samples).  When microphone feedback (FBX) is not in use (BGV_SPEAKER project) you may experiment with any value from 60 to 512.  Higher numbers will cause more latency but will allow more DPS functions to be enabled.   When FBX is enabled (BGV_MIC project) you must use power-of-2 values such at 64, 128, 256 (maximum).

#define BITS_16

This selects the 16 bit or 32 bit PCM to floating point conversion function.  Comment this out for 32 bit mode.

#define USE_INTERNAL_CODEC

This selects the native NUC505 audio codec (configured for analog input by default) or external IIS.  Comment out for external IIS mode.

#define RATE_48k

Selects 44.1kHZ or 48kHZ sample rate.  Comment out for 44.1kHz operation.

All other functions are described in the DPS SDK NUC505 API Description.

main.c

This file handles NUC505 Audio Board I2S codec, UART and DMA setup.

Lines ~55 to ~58 set the volume levels of the analog to digital (ADC = input) and digital to analog (DAC = output) audio signal converters:

DAC

I2S_SET_INTERNAL_CODEC(I2S, 0x08, 0x01); // DAC Left Volume
I2S_SET_INTERNAL_CODEC(I2S, 0x09, 0x01); // DAC Right Volume

The DAC analog volume level is adjusted in the 3rd input variable (in bold above).  The range is 0x00 (0dB maximum) to 0x1E (-60dB minimum) to 0x1F (mute).  Steps are -2dB.

ADC

I2S_SET_INTERNAL_CODEC(I2S, 0x10, 0x00); // ADC Left Volume
I2S_SET_INTERNAL_CODEC(I2S, 0x11, 0x00); // ADC Right Volume

The ADC volume level is adjusted in the 3rd input variable (in bold above).  The range is 0x0 (0dB unity gain) to 0xE (+22.4dB maximum gain) in 1.6dB steps.  0xF is mute.

The main() function contains the function calls that set up DPS (lines ~149 to ~156):

DPS_GlobalInitialize();

This initializes the DPS library.

 DPS_EnableDPS();

This enables DPS processing.

 DPS_EnableStereoWidening();

This enables Stereo Enhancement.

 DPS_LoadPreset(1);

This loads preset (DPS Profile) #2.

New versions of the Sample Project include code to connect NUC505 GPIO pins to DPS API functions.  This provides examples for using the NUC505 and DPS as an SoC for many audio devices.

Headphones and other new features are clearly commented in the latest DPS.h file.

indices.c

This file is generated by the DPS Profile Creator.  It contains 5 DPS Profile parameter sets in the form of an array of indexes.  The presets included in the sample project have been designed to demonstrate DPS processing on a portable speaker:

  • preset 0 = Loud Music – calibrated for loud music with a lot of high frequency content.  Best for Dance, Pop and Rock music.
  • preset 1 = Quieter Music – calibrated for jazz, piano and other quieter performances.   Use this preset if you hear distortion in preset 0.
  • preset 2 = Movies – This preset has enhanced stereo enhancement and automatic volume control for movies.
  • preset 3 = Voice/High Noise Environment – This preset makes the speaker very loud to overcome background noise.
  • preset 4 = No Effect – All DPS features are bypassed.  Using this preset (instead of turning DPS off) allows the User Volume Control to work when evaluating the effect of DPS processing.

These profiles may be selected using the API or UART commands.  Click Here to learn more about generating the indices.c file to customize DPS for your audio device.

nuc505_isr.c

This is the interrupt service routine (ISR).  It handles the direct memory access (DMA) buffers where the audio processing takes place.

The first part of the file (lines ~31 to ~136) handles the 32 or 16 bit integer to floating point conversion functions.

Line ~137 uses the RATE_48k directive to select between Dynamic Stereo Enhancement (44.1kHz) and Simple Stereo Enhancement (48kHz).

Line ~161 is the buffer handling function.  The following functions are performed on an I2S audio stream:

  1. Convert an integer audio stream to floating point samples.
  2. Apply the DPS Noise Gate.
  3. Apply StereoExpand
    1. This applies StereoWiden if the NUC505 isin 44.1kHz sample rate mode.
    2. SimpleStereoWiden is applied if the NUC505 is in 48k mode.
    3. This automatic selection may be overridden by calling StereoWiden (Dynamic Stereo Enhancement) or SimpleStereoWiden (Simple Stereo Enhancement) instead of StereoExpand.
  4. Apply DPS dynamics and equalization to left channel.
  5. Apply DPS dynamics and equalization to right channel.
  6. Convert floating point samples to an integer audio stream.

Notice there are 2 alternating buffers used in this function.  The DPS functions must be called exactly the same way for both buffers:

void I2S_IRQHandler(void)
{
	uint32_t u32I2SIntFlag;

	u32I2SIntFlag = I2S_GET_INT_FLAG(I2S, (I2S_STATUS_RDMATIF_Msk | I2S_STATUS_RDMAEIF_Msk));

	/* Two alternating DMA buffers triggered by IRQ */

Buffer #1

if (u32I2SIntFlag & I2S_STATUS_RDMATIF_Msk)  //process buffer 1
	{
		I2S_CLR_INT_FLAG(I2S, I2S_STATUS_RDMATIF_Msk);

		fixedToFloat(&PcmRxBuff[0][0], xf_L, BUFF_LEN);
		fixedToFloat(&PcmRxBuff[0][1], xf_R, BUFF_LEN);

		NoiseGateProcess(xf_L, xf_R);
		StereoExpand(xf_L, xf_R);
		DPS_Left(xf_L);
		DPS_Right(xf_R);

		floatToFixed(xf_L, &PcmTxBuff[0][0], BUFF_LEN);
		floatToFixed(xf_R, &PcmTxBuff[0][1], BUFF_LEN);
	}

Buffer #2

else if (u32I2SIntFlag & I2S_STATUS_RDMAEIF_Msk) //process buffer 2
	{
		I2S_CLR_INT_FLAG(I2S, I2S_STATUS_RDMAEIF_Msk);
		if ( s_flag1 == 0 )
		{
			s_flag1 = 1;
			I2S_ENABLE_TXDMA(I2S);
			I2S_ENABLE_TX(I2S);
		}

		fixedToFloat(&PcmRxBuff[1][0], xf_L, BUFF_LEN);
		fixedToFloat(&PcmRxBuff[1][1], xf_R, BUFF_LEN);

		NoiseGateProcess(xf_L, xf_R);
		StereoExpand(xf_L, xf_R);
		DPS_Left(xf_L);
		DPS_Right(xf_R);

		floatToFixed(xf_L, &PcmTxBuff[1][0], BUFF_LEN);
		floatToFixed(xf_R, &PcmTxBuff[1][1], BUFF_LEN);
	}
}

NOTE: If a Bongiovi DPS audio processing function is not needed (for example – a noise gate is unnecessary on an I2S digital stream) the function may be removed from the processing loop.  See Platform Considerations for details.