Test the Synth sound functions of Pokitto

Dependencies:   PokittoLib

SynthTest - Pokitto synth demo

To test this program, simply press "Import into Compiler" button on the right!

/media/uploads/Pokitto/synthtest.jpg

SynthTest.cpp

Committer:
Pokitto
Date:
2018-01-30
Revision:
2:91c41852a646
Parent:
0:e0bd5da25882
Child:
5:09131ded851b

File content as of revision 2:91c41852a646:

#include "Pokitto.h"
#include "Synth.h"
#include "dma_11u6x.h"

Pokitto::Core game;
Pokitto::Display disp;
Pokitto::Sound snd;
Pokitto::Buttons btn;

uint8_t mysine[] = {
0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,
0x98,0x9b,0x9e,0xa2,0xa5,0xa7,0xaa,0xad,
0xb0,0xb3,0xb6,0xb9,0xbc,0xbe,0xc1,0xc4,
0xc6,0xc9,0xcb,0xce,0xd0,0xd3,0xd5,0xd7,
0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,
0xea,0xeb,0xed,0xee,0xf0,0xf1,0xf3,0xf4,
0xf5,0xf6,0xf8,0xf9,0xfa,0xfa,0xfb,0xfc,
0xfd,0xfd,0xfe,0xfe,0xfe,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfd,
0xfd,0xfc,0xfb,0xfa,0xfa,0xf9,0xf8,0xf6,
0xf5,0xf4,0xf3,0xf1,0xf0,0xee,0xed,0xeb,
0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
0xda,0xd7,0xd5,0xd3,0xd0,0xce,0xcb,0xc9,
0xc6,0xc4,0xc1,0xbe,0xbc,0xb9,0xb6,0xb3,
0xb0,0xad,0xaa,0xa7,0xa5,0xa2,0x9e,0x9b,
0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,
0x67,0x64,0x61,0x5d,0x5a,0x58,0x55,0x52,
0x4f,0x4c,0x49,0x46,0x43,0x41,0x3e,0x3b,
0x39,0x36,0x34,0x31,0x2f,0x2c,0x2a,0x28,
0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,
0x15,0x14,0x12,0x11,0xf,0xe,0xc,0xb,
0xa,0x9,0x7,0x6,0x5,0x5,0x4,0x3,
0x2,0x2,0x1,0x1,0x1,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x2,
0x2,0x3,0x4,0x5,0x5,0x6,0x7,0x9,
0xa,0xb,0xc,0xe,0xf,0x11,0x12,0x14,
0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
0x25,0x28,0x2a,0x2c,0x2f,0x31,0x34,0x36,
0x39,0x3b,0x3e,0x41,0x43,0x46,0x49,0x4c,
0x4f,0x52,0x55,0x58,0x5a,0x5d,0x61,0x64,
0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c
};

int tonefreq=46;
uint8_t amplitude = 255;//127;
uint8_t wavetype = 1, arpmode=1;
uint32_t changed = 1;
char notestr[6];
uint8_t sbindx=0,sbx=0,prevy=0;

/* Size of the source and destination buffers in 32-bit words.
   Allowable values  = 126, 256, 512, or 1024 */
#define SIZE_BUFFERS            (256)

/* Source and destination buffers */
//uint32_t src[SIZE_BUFFERS], dst[SIZE_BUFFERS];
uint8_t src[SIZE_BUFFERS], dst[SIZE_BUFFERS];

/* DMA completion flag */
static volatile bool dmaDone;

// IRQ handlers have to be extern "C" in mbed!!!!!!!
extern "C" void DMA_IRQHandler(void)
{
	/* Rrror interrupt on channel 0? */
	if ((Chip_DMA_GetIntStatus(LPC_DMA) & DMA_INTSTAT_ACTIVEERRINT) != 0) {
		/* This shouldn't happen for this simple DMA example, so set the LED
		   to indicate an error occurred. This is the correct method to clear
		   an abort. */
		Chip_DMA_DisableChannel(LPC_DMA, DMA_CH0);
		while ((Chip_DMA_GetBusyChannels(LPC_DMA) & (1 << DMA_CH0)) != 0) {}
		Chip_DMA_AbortChannel(LPC_DMA, DMA_CH0);
		Chip_DMA_ClearErrorIntChannel(LPC_DMA, DMA_CH0);
		Chip_DMA_EnableChannel(LPC_DMA, DMA_CH0);
		//Board_LED_Set(0, true);
	}

	/* Clear DMA interrupt for the channel */
	Chip_DMA_ClearActiveIntAChannel(LPC_DMA, DMA_CH0);

	dmaDone = true;
}

void modifysrc(int j) {
    for (uint32_t i=0; i<SIZE_BUFFERS;i++) {
            src[i] = random(0,255);
    }
}

int main()
{
    modifysrc(0);
    game.begin();
    /* DMA part */
    DMA_CHDESC_T dmaDesc;
	int i;

	uint32_t startTime, ticks[3];
    /* DMA initialization - enable DMA clocking and reset DMA if needed */
	Chip_DMA_Init(LPC_DMA);
    /* Enable DMA controller and use driver provided DMA table for current descriptors */
	Chip_DMA_Enable(LPC_DMA);
	Chip_DMA_SetSRAMBase(LPC_DMA, DMA_ADDR(Chip_DMA_Table));
	/* Setup channel 0 for the following configuration:
	   - High channel priority
	   - Interrupt A fires on descriptor completion */
	Chip_DMA_EnableChannel(LPC_DMA, DMA_CH0);
	Chip_DMA_EnableIntChannel(LPC_DMA, DMA_CH0);
	Chip_DMA_SetupChannelConfig(LPC_DMA, DMA_CH0,
								(DMA_CFG_HWTRIGEN | DMA_CFG_TRIGTYPE_EDGE | DMA_CFG_TRIGPOL_HIGH |
								 DMA_CFG_BURSTPOWER_128 | DMA_CFG_CHPRIORITY(0)));

    /* DMA descriptor for memory to memory operation - note that addresses must
	   be the END address for src and destination, not the starting address.
	     DMA operations moves from end to start. */
	//dmaDesc.source = DMA_ADDR(&src[SIZE_BUFFERS - 1]) + 3;
	//dmaDesc.dest = DMA_ADDR(&dst[SIZE_BUFFERS - 1]) + 3;
	dmaDesc.source = DMA_ADDR(&src[SIZE_BUFFERS - 1]);
	//dmaDesc.dest = DMA_ADDR(&dst[SIZE_BUFFERS - 1]);
	dmaDesc.dest = DMA_ADDR(&game.display.screenbuffer[SIZE_BUFFERS - 1]);
	dmaDesc.next = DMA_ADDR(0);

	/* Enable DMA interrupt */
	uint32_t rtr = NVIC->ISER[0];
	NVIC_EnableIRQ(DMA_IRQn);

    /* Reset timer and perform a bunch memory to memory moves with DMA */

	for (i = 0; i < 100; i++) {
		dmaDone = false;

		//modifyData(src, dst, SIZE_BUFFERS);
        modifysrc(i);

		/* Setup transfer descriptor and validate it */
		Chip_DMA_SetupTranChannel(LPC_DMA, DMA_CH0, &dmaDesc);
		Chip_DMA_SetValidChannel(LPC_DMA, DMA_CH0);

		/* Setup data transfer and software trigger in same call */
		/*Chip_DMA_SetupChannelTransfer(LPC_DMA, DMA_CH0,
									  (DMA_XFERCFG_CFGVALID | DMA_XFERCFG_SETINTA | DMA_XFERCFG_SWTRIG |
									   DMA_XFERCFG_WIDTH_32 | DMA_XFERCFG_SRCINC_1 | DMA_XFERCFG_DSTINC_1 |
									   DMA_XFERCFG_XFERCOUNT(SIZE_BUFFERS)));*/
        Chip_DMA_SetupChannelTransfer(LPC_DMA, DMA_CH0,
									  (DMA_XFERCFG_CFGVALID | DMA_XFERCFG_SETINTA | DMA_XFERCFG_SWTRIG |
									   DMA_XFERCFG_WIDTH_8 | DMA_XFERCFG_SRCINC_1 | DMA_XFERCFG_DSTINC_0 |
									   DMA_XFERCFG_XFERCOUNT(SIZE_BUFFERS)));
		/* Wait for DMA completion */
		while (dmaDone == false) {
			if (game.update()) {
                game.display.color=3;
                game.display.print("Hello! ");
			}

		}

	}


    snd.setVolume(snd.getMaxVol()); // volume to max level depending on headset/speaker safety level
    disp.persistence = true;
    disp.color=wavetype+1;
    disp.bgcolor=0;
    uint8_t sbindx=0;
    int oldvol=0;
    int linecenter = (disp.height/4); // center oscilloscope line vertically
    linecenter *=2;
    linecenter += 0;
    snd.ampEnable(1);
    snd.playTone(1,tonefreq,amplitude,wavetype,arpmode);
    //snd.playTone(1,100,255,0);
    // want to have 2 oscillators 1 octave apart ?
    snd.playTone(2,tonefreq+12,amplitude,wavetype,arpmode);

    disp.clear();
    disp.print("Frq:");
    getNoteString(notestr,tonefreq);
    disp.println(notestr);
    disp.print("Vol:");
    disp.println((int)amplitude);
    disp.print("Wav:");
    disp.print((int)wavetype);
    switch (wavetype) {
    case 0:
        disp.println(" Off");break;
    case 1:
        disp.println(" Square");break;
    case 2:
        disp.println(" Saw");break;
    case 3:
        disp.println(" Triang");break;
    case 4:
        disp.println(" Noise");break;
    case 5:
        disp.println(" SqNois");break;
    }
    disp.print("HWvol:");
    disp.println((int)snd.getVolume());
    disp.lcdRefresh(disp.screenbuffer);



    while (game.isRunning()) {

        #ifdef POK_SIM
            #define DEBOU 2048*32
        #else
            #define DEBOU 256
        #endif

        /*
        uint32_t* j = (uint32_t*)0x5000e204;
        *j = 0xab;//(0x1F*(uint32_t)val++)>>8;

        Chip_DMA_SetupTranChannel(LPC_DMA, DMA_CH0, &dmaDesc);
		Chip_DMA_SetValidChannel(LPC_DMA, DMA_CH0);
		dmaDesc.source = DMA_ADDR(&mysine[255]);
            dmaDesc.dest = DMA_ADDR(j);
            dmaDesc.next = DMA_ADDR(0);*/

		/*if (!val) {
            dmaDesc.source = DMA_ADDR(&mysine[255]);
            dmaDesc.dest = DMA_ADDR(&soundbuf[255]);
            dmaDesc.next = DMA_ADDR(0);
		} else {
            dmaDesc.source = DMA_ADDR(&src[255]);
            dmaDesc.dest = DMA_ADDR(&soundbuf[255]);
            dmaDesc.next = DMA_ADDR(0);
		}*/
		/*
		Chip_DMA_SetupChannelTransfer(LPC_DMA, DMA_CH0,
									  (DMA_XFERCFG_CFGVALID | DMA_XFERCFG_SETINTA | DMA_XFERCFG_SWTRIG |
									   DMA_XFERCFG_WIDTH_8 | DMA_XFERCFG_SRCINC_1 | DMA_XFERCFG_DSTINC_0 |
									   DMA_XFERCFG_XFERCOUNT(255)));*/

		//0x1f*
		//val=1-val;
		//fill buffer



        if (changed == 0) {
            if(btn.upBtn()) { amplitude++; changed = DEBOU; }
            if(btn.downBtn()) { amplitude--; changed = DEBOU; }
            if(btn.leftBtn() && (tonefreq > 0)) { tonefreq --; changed = DEBOU; }
            if(btn.rightBtn() &&  (tonefreq < 88)) { tonefreq ++; changed = DEBOU; }
            if(btn.released(BTN_A) && wavetype > 0 ) { wavetype--; changed = DEBOU*10;}
            if(btn.released(BTN_B) && wavetype < 5 ) { wavetype++; changed = DEBOU*10;}
            if (snd.getVolume() != oldvol) changed=DEBOU;

            if (changed) {
                    disp.clear();
                    disp.color=0;//owavetype+1;
                    disp.fillRectangle(0,0,109,34);
                    disp.color=wavetype+1;
                    disp.bgcolor=0;
                    disp.print("Frq:");
                    getNoteString(notestr,tonefreq);
                    disp.println(notestr);
                    disp.print("Vol:");
                    disp.println((int)amplitude);
                    disp.print("Wav:");
                    disp.print((int)wavetype);
                    switch (wavetype) {
                    case 0:
                        disp.println(" Off");break;
                    case 1:
                        disp.println(" Square");break;
                    case 2:
                        disp.println(" Saw");break;
                    case 3:
                        disp.println(" Triang");break;
                    case 4:
                        disp.println(" Noise");break;
                    case 5:
                        disp.println(" SqNois");break;
                    }
                    disp.print("HWvol:");
                    disp.println((int)snd.getVolume());
                    snd.playTone(1,tonefreq,amplitude,wavetype,arpmode);
                    oldvol = (int) snd.getVolume();
                    // want to have 2 oscillators 1 octave apart ?
                    snd.playTone(2,tonefreq+12,amplitude,wavetype,arpmode);
            }
        } else changed--;
        disp.color=0;
        disp.drawColumn(sbx,38,disp.height);
        disp.color=wavetype+1;
        uint8_t tindex = sbindx*2;
        int16_t y = linecenter + (((int)128-(soundbuf[tindex]))>>2);
        disp.drawLine(sbx-1,prevy,sbx,y);
        game.update();
        disp.color=0;
        prevy=y;
        sbx++;sbindx++;
        if (sbx>disp.width-1) {sbx=0;}
    }
    return 0; // good manners!
}