Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: YATTT sd_map_test cPong SnowDemo ... more
PokittoLib
Library for programming Pokitto hardware
How to Use
- Import this library to online compiler (see button "import" on the right hand side
- DO NOT import mbed-src anymore, a better version is now included inside PokittoLib
- Change My_settings.h according to your project
- Start coding!
Diff: POKITTO_HW/HWSound.cpp
- Revision:
- 42:798b5d67b372
- Parent:
- 41:e667167aa9d8
- Child:
- 43:6183b12dd99c
--- a/POKITTO_HW/HWSound.cpp Wed Apr 25 14:00:49 2018 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,495 +0,0 @@
-/**************************************************************************/
-/*!
- @file HWSound.cpp
- @author Jonne Valola
-
- @section LICENSE
-
- Software License Agreement (BSD License)
-
- Copyright (c) 2016, Jonne Valola
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. Neither the name of the copyright holders nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/**************************************************************************/
-
-#include "mbed.h"
-#include "HWSound.h"
-//#include "MCP4018.h"
-#include "SoftwareI2C.h"
-#include "Pokitto_settings.h"
-#include "PokittoDisk.h"
-#include "PokittoGlobs.h"
-#include "Synth.h"
-#include "timer_11u6x.h"
-#include "clock_11u6x.h"
-#include "HWLCD.h"
-//#include "beat_11025.h"
-
-
-Pokitto::Sound __shw;
-
-using namespace Pokitto;
-
-#ifndef POK_SIM
-#if POK_ENABLE_SOUND
-pwmout_t* obj = &audiopwm;
-#endif
-#endif
-
-/** Sound Variables **/
-#if (POK_STREAMING_MUSIC > 0)
- unsigned char buffers[4][BUFFER_SIZE];
- volatile int currentBuffer = 0, oldBuffer = 0;
- volatile int bufindex = 0, vol=1;
- volatile unsigned char * currentPtr;
- volatile unsigned char * endPtr;
- int8_t streamvol=3;
- uint32_t streamcounter=0;
- uint8_t streamstep=0;
-#endif
-
-#if POK_ENABLE_SOUND > 0
- pwmout_t Pokitto::audiopwm; // this way (instead of PwmOut class) pwm doesn't start screaming until it is initialized !
- //Ticker Pokitto::audio;
-
-using namespace Pokitto;
-
-/** stream output and status */
-uint8_t Pokitto::streambyte,Pokitto::streamon;
-
-uint8_t soundbuf[SBUFSIZE];
-uint8_t Pokitto::HWvolume=0;
-uint16_t soundbufindex;
-uint8_t* soundbufptr;
-
-bool volpotError=false; //test for broken MCP4018
-
-uint16_t soundbyte;
-
-
-#if POK_USE_DAC > 0
-#if POK_BOARDREV == 1
- /** 2-layer board rev 1.3 **/
- DigitalOut dac0(P1_6);
- DigitalOut dac1(P1_0);
- DigitalOut dac2(P1_16);
- DigitalOut dac3(P0_19);
- DigitalOut dac4(P0_17);
- DigitalOut dac5(P1_12);
- DigitalOut dac6(P1_15);
- DigitalOut dac7(P1_8);
-#else
- /** 4-layer board rev 2.1 **/
- DigitalOut dac0(P1_28);
- DigitalOut dac1(P1_29);
- DigitalOut dac2(P1_30);
- DigitalOut dac3(P1_31);
- /* has daniel made a mistake ?*/
- DigitalOut dac4(P2_20);
- DigitalOut dac5(P2_21);
- DigitalOut dac6(P2_22);
- DigitalOut dac7(P2_23);
-
- DigitalOut amp(P1_17);
-
-#endif // POK_BOARDREV
-#endif // POK_USE_DAC
-
-#if POK_BOARDREV == 2
-//MCP4018 volpot(P0_5,P0_4);
-
-/**
- * @brief Handle interrupt from 32-bit timer 0
- * @return Nothing
- */
-
-uint32_t p=0;
-uint8_t pixx=0, pixy=0;
-
-extern "C" void TIMER32_0_IRQHandler(void)
-{
- if (Chip_TIMER_MatchPending(LPC_TIMER32_0, 1)) {
- Chip_TIMER_ClearMatch(LPC_TIMER32_0, 1);
- //pokSoundBufferedIRQ();
- #if POK_GBSOUND > 0
- /** GAMEBUINO SOUND **/
- Pokitto::audio_IRQ();
- #else
- /** NOT GAMEBUINO SOUND **/
- #if POK_SOUND_BUFFERED
- pokSoundBufferedIRQ();
- #else
- pokSoundIRQ();
- #endif
- #endif
- }
-}
-
-
-void initHWvolumecontrol() {
- HWvolume=0;
- volpotError=true;
- //if (volpot.put(HWvolume)) volpotError=true; //try if MCP4018 answers
- setHWvolume(VOLUME_STARTUP);
-}
-
-int Pokitto::setHWvolume(uint8_t v) {
- HWvolume = 0x7F&v;
- //if (!volpotError) return volpot.put(HWvolume); //use normal I2C
- /* fallback method for broken MCP4018 */
- SoftwareI2C swvolpot(P0_4, P0_5); //swapped SDA,SCL
- swvolpot.write(0x5e,HWvolume);
- return HWvolume;
-}
-
-uint8_t Pokitto::getHWvolume() {
- return HWvolume;
-}
-
-void Pokitto::changeHWvolume(int8_t v) {
- int temp = HWvolume + v;
- if (temp < 0) temp = 0; //prevent volume "looparound" than can make a massive crack
- if (temp > 127) temp = 127;
- setHWvolume(temp);
-}
-
- uint8_t Pokitto::ampIsOn() {
- return amp;
- }
-
- void Pokitto::ampEnable(uint8_t v) {
- if (v>1) v=1; // limit against funny values
- amp=v;
- }
-#endif // POK_BOARDREV == 2
-
-void Pokitto::dac_write(uint8_t value) {
- #if POK_USE_DAC > 0
- #if POK_BOARDREV == 1 // was 1
- if (value & 1) SET_DAC0 else CLR_DAC0;
- value >>= 1;
- if (value & 1) SET_DAC1 else CLR_DAC1;
- value >>= 1;
- if (value & 1) SET_DAC2 else CLR_DAC2;
- value >>= 1;
- if (value & 1) SET_DAC3 else CLR_DAC3;
- value >>= 1;
- if (value & 1) SET_DAC4 else CLR_DAC4;
- value >>= 1;
- if (value & 1) SET_DAC5 else CLR_DAC5;
- value >>= 1;
- if (value & 1) SET_DAC6 else CLR_DAC6;
- value >>= 1;
- if (value & 1) SET_DAC7 else CLR_DAC7;
- #else
-
- //val = value<<28; //lower 4 bits go higher - because port mask is used, no AND is needed to clear bits
- //val += value<<(15-4); //higher 4 bits go lower. No need to shift by 15 because bits are in the higher nibble
- /* daniel has made a mistake with ports */
- //val = ((value&0x70)<<(28-4)); //higher 4 bits go higher - because port mask is used, no AND is needed to clear bits
- //val += value<<(15); //lower 4 bits go lower. No need to shift by 15 because bits are in the higher nibble
- //SET_MASK_DAC;
- //LPC_GPIO_PORT->MPIN[1] = val; // write bits to port
- //CLR_MASK_DAC;
- /* fixed here */
- #define MASKED_DAC 0
- #if MASKED_DAC
- uint32_t val;
- val=value;
- SET_MASK_DAC_LO;
- LPC_GPIO_PORT->MPIN[1] = val<<28; // write lower 4 bits to port
- CLR_MASK_DAC_LO;
- SET_MASK_DAC_HI;
- LPC_GPIO_PORT->MPIN[2] = val<<(20-4); // write bits to port
- CLR_MASK_DAC_HI;
- #else
- if (value & 1) SET_DAC0 else CLR_DAC0;
- value >>= 1;
- if (value & 1) SET_DAC1 else CLR_DAC1;
- value >>= 1;
- if (value & 1) SET_DAC2 else CLR_DAC2;
- value >>= 1;
- if (value & 1) SET_DAC3 else CLR_DAC3;
- value >>= 1;
- if (value & 1) SET_DAC4 else CLR_DAC4;
- value >>= 1;
- if (value & 1) SET_DAC5 else CLR_DAC5;
- value >>= 1;
- if (value & 1) SET_DAC6 else CLR_DAC6;
- value >>= 1;
- if (value & 1) SET_DAC7 else CLR_DAC7;
- #endif //MASKED_DAC
- //CLR_MASK_DAC;
- #endif // BOARDREV
- #endif
-}
-
-/** SOUND INIT **/
-void Pokitto::soundInit() {
- #if POK_ENABLE_SOUND > 0
- uint32_t timerFreq;
- #if POK_USE_PWM
-
- pwmout_init(&audiopwm,POK_AUD_PIN);
- pwmout_period_us(&audiopwm,POK_AUD_PWM_US); //was 31us
- pwmout_write(&audiopwm,0.1f);
- #endif
-
- //#if POK_GBSOUND > 0
- /** GAMEBUINO SOUND **/
- //audio.attach_us(&audio_IRQ, 1000000/(POK_AUD_FREQ>>0));
- //#else
- /** NOT GAMEBUINO SOUND **/
- //audio.attach_us(&pokSoundBufferedIRQ, 1000000/(POK_AUD_FREQ>>0));
- /* Initialize 32-bit timer 0 clock */
- Chip_TIMER_Init(LPC_TIMER32_0);
-
- /* Timer rate is system clock rate */
- timerFreq = Chip_Clock_GetSystemClockRate();
-
- /* Timer setup for match and interrupt at TICKRATE_HZ */
- Chip_TIMER_Reset(LPC_TIMER32_0);
-
- /* Enable both timers to generate interrupts when time matches */
- Chip_TIMER_MatchEnableInt(LPC_TIMER32_0, 1);
-
- /* Setup 32-bit timer's duration (32-bit match time) */
- Chip_TIMER_SetMatch(LPC_TIMER32_0, 1, (timerFreq / POK_AUD_FREQ));
-
- /* Setup both timers to restart when match occurs */
- Chip_TIMER_ResetOnMatchEnable(LPC_TIMER32_0, 1);
-
- /* Start both timers */
- Chip_TIMER_Enable(LPC_TIMER32_0);
-
- /* Clear both timers of any pending interrupts */
- #define TIMER_32_0_IRQn 18
- NVIC_ClearPendingIRQ((IRQn_Type)TIMER_32_0_IRQn);
-
- /* Redirect IRQ vector - Jonne*/
- NVIC_SetVector((IRQn_Type)TIMER_32_0_IRQn, (uint32_t)&TIMER32_0_IRQHandler);
-
- /* Enable both timer interrupts */
- NVIC_EnableIRQ((IRQn_Type)TIMER_32_0_IRQn);
- //#endif // POK_GAMEBUINO_SUPPORT
-
- //emptySong();
- //emptyOscillators();
- //emptyBlocks();
- //emptyPatches();
- #ifdef TEST_SOUND
- testOsc();
- #endif // TEST_SOUND
- #if POK_BOARDREV == 2
- initHWvolumecontrol();
- #endif
-
- #if POK_ENABLE_SYNTH
- emptyOscillators();
- #endif
-
-
- #endif // POK_ENABLE_SOUND
-
-}
-
-
-uint8_t Pokitto::streamPaused() {
- return !streamon;
-}
-
-void Pokitto::pauseStream() {
- streamon=0;
-}
-
-void Pokitto::playStream() {
- streamon=1;
-}
-
-
-void pokPauseStream() {
- streamon=0;
-}
-
-void pokPlayStream() {
- streamon=1;
-}
-
-
-
-inline void pokSoundBufferedIRQ() {
- uint8_t output = soundbuf[soundbufindex+=Pokitto::streamon];
- if (soundbufindex==SBUFSIZE) soundbufindex=0;
- //if (p==sizeof(beat_11025_raw)) p=0;
- //soundbuf[soundbufindex++] = output;
- //uint32_t t_on = (uint32_t)(((obj->pwm->MATCHREL0)*output)>>8); //cut out float
- //obj->pwm->MATCHREL1 = t_on;
- dac_write(output);
-
- //setDRAMpoint(pixx, pixy);
-}
-
-inline void pokSoundIRQ() {
- #if POK_ENABLE_SOUND > 0
- //#define TICKY 0xFFFF //160
- //#define INCY 409
- uint8_t output=0;
- streamon=1;
- //if (test==TICKY) test=0;
- //if (test<(TICKY/2)) { tpin=1; pwmout_write(&audiopwm,(float)0/(float)255);}//dac_write(0);}
- //else {tpin=0; pwmout_write(&audiopwm,(float)255/(float)255);}//dac_write(64);}
- //test+=INCY;
- //return;
- #ifndef POK_SIM
- #if POK_USE_PWM
- pwmout_t* obj = &audiopwm;
- #endif
- #endif
- #if POK_STREAMING_MUSIC > 0
- #if POK_STREAMFREQ_HALVE
- streamstep = 1-streamstep;
- #else
- streamstep = 1;
- #endif // POK_STREAMFREQ_HALVE
- streamstep &= streamon; // streamon is used to toggle SD music streaming on and off
- if (streamstep) {
- output = (*currentPtr++);
- if(streamvol && streamon) {
- output >>= 3-streamvol;
- streambyte = output;
- } else {
- streambyte = 0; // duty cycle
- output = 0;
- }
- if (currentPtr >= endPtr)
- {
- currentBuffer++;
- if (currentBuffer==4) currentBuffer=0;
- currentPtr = buffers[currentBuffer];
- endPtr = currentPtr + BUFFER_SIZE;
- }
- }
- #endif // POK_STREAMING_MUSIC
-
- /** DO ADDITIONAL SOUND PROCESSING (NOT STREAM) OF SOUND HERE **/
-
- #if POK_ENABLE_SYNTH
- /** if song is being played from sd **/
- if (playing) {
- notetick++;
- updatePlayback();
- }
- /** oscillators update **/
- osc1.count += osc1.cinc + (osc1.pitchbend >> 4); // counts to 65535 and overflows to zero WAS 8 !
- osc2.count += osc2.cinc + (osc2.pitchbend >> 4); // counts to 65535 and overflows to zero
- osc3.count += osc3.cinc + (osc3.pitchbend >> 4); // counts to 65535 and overflows to zero
- Marr[tick](); // call mixing function
- --tick;
-
- /** mixing oscillator output **/
-
- uint16_t op = (uint16_t) ((osc1.output)*(osc1.vol>>8))>>9;// >> 2 osc1.vol Marr;
- op += (uint16_t) ((osc2.output)*(osc2.vol>>8))>>9;// >> 2 osc1.vol Marr;
- op += (uint16_t) ((osc3.output)*(osc3.vol>>8))>>9;// >> 2 osc1.vol Marr;
- output = (uint8_t) op;
-
- #endif // POK_ENABLE_SYNTH
-
- #ifndef POK_SIM
- /** HARDWARE **/
- #if POK_ENABLE_SOUND > 0
- #if POK_STREAMING_MUSIC > 0
- /** sound is enabled, streaming is enabled */
- #if POK_STREAM_TO_DAC > 0
- /** stream goes to DAC */
- #if POK_USE_DAC > 0
- dac_write(streambyte>>__shw.headPhoneLevel); // duty cycle
- #endif // POK_USE_DAC
- #else
- /** stream goes to PWM */
- if (streamstep) {
- //pwmout_write(&audiopwm,(float)streambyte/(float)255);
- #if POK_USE_PWM
- uint32_t t_on = (uint32_t)((((obj->pwm->MATCHREL0)*streambyte)>>8)>>__shw.headPhoneLevel); //cut out float
- obj->pwm->MATCHREL1 = t_on;
- #endif
- //dac_write((uint8_t)streambyte); // duty cycle
- }
- #endif // POK_STREAM_TO_DAC
- #endif // POK_STREAMING_MUSIC
- #if POK_STREAM_TO_DAC > 0
- /** synth goes to PWM */
- //pwmout_write(&audiopwm,(float)output/(float)255);
- #if POK_USE_PWM
- uint32_t t_on = (uint32_t)((((obj->pwm->MATCHREL0)*output)>>8)>>__shw.headPhoneLevel); //cut out float
- obj->pwm->MATCHREL1 = t_on;
- #endif
- #else // POK_STREAMING_MUSIC
- dac_write((uint8_t)output>>__shw.headPhoneLevel); // SYNTH to DAC
- #endif
- soundbyte = (output+streambyte)>>1;
- soundbuf[soundbufindex++]=soundbyte;
- if (soundbufindex==256) soundbufindex=0;
- #endif //POK_ENABLE_SOUND
- #endif // HARDWARE
-#endif //POK_ENABLE_SOUND
-}
-
-
-void Pokitto::updateSDAudioStream() {
- #ifndef NOPETITFATFS
- if (streamPaused()) return;
-
- #if POK_STREAMING_MUSIC > 0
- if (oldBuffer != currentBuffer) {
- if (currentBuffer==0) fileReadBytes(&buffers[3][0],BUFFER_SIZE);
- else if (currentBuffer==1) fileReadBytes(&buffers[0][0],BUFFER_SIZE);
- else if (currentBuffer==2) fileReadBytes(&buffers[1][0],BUFFER_SIZE);
- else fileReadBytes(&buffers[2][0],BUFFER_SIZE);
- oldBuffer = currentBuffer;
- streamcounter += BUFFER_SIZE;
- } else return;
-
- #ifndef POK_SIM
- if ( streamcounter > fs.fsize - (BUFFER_SIZE*6)) {
- #else
- if ( streamcounter > getFileLength() - (BUFFER_SIZE*6)) {
- #endif
- streamcounter=0;
- #if POK_STREAM_LOOP
- fileRewind();
- #else
- pokPauseStream();
- #endif
- }
- #endif
- #endif // NOPETITFATFS
-}
-
-
-#endif // POK_ENABLE_SOUND
-
-
-