MIDI file player?

Post here first, or if you can't find a relevant section!
GVisser
Posts: 19
Joined: Thu Jun 11, 2020 5:17 pm
Answers: 1
Location: Hatfield, UK

MIDI file player?

Post by GVisser »

Hi all,

I am in search of a simple midi file player that I could use in my project, so was looking at https://github.com/JBSchueler/arduino-midi-player_stm32.

The problem is that the sketch won't compile for my STM32F401. Among other errors it is complaining about the HardwareTimer

Code: Select all

arduino-midi-player_stm32:43:24: error: invalid conversion from 'int' to 'TIM_TypeDef*' [-fpermissive]
   43 | HardwareTimer pwmtimer(3);
The code also seems to be using uint8 and uint16 instead of uint8_t and uint16_t

So my question is: Is there a simple way to get this code to work for my core or would I need to 'port' the code?

Remember: I am a newbie so please please little words in your answers *chuckle*

PS. If you happen to know of another midi file player sketch that I could use, please let me know that as well :-)
by Bakisha » Fri Jun 26, 2020 9:18 pm
Hi, i might help a little bit since once i did project with audio with PWM. After a quick look on a sketch, i changed few line, to be able to compile on official core:

Code: Select all

//HardwareTimer pwmtimer(3);
HardwareTimer *pwmtimer = new HardwareTimer(TIM3);

void PWM_Init( void )
{
  /*
    Timer3.attachCompare1Interrupt( irq_handler_timer3 ); // <-- this will set all the needed clokcks and int vectors
    pwmtimer.setPrescaleFactor(9);
    pwmtimer.setCount(0);
    pwmtimer.setOverflow(255);
    pinMode(Spkr, PWM);
    pwmWritefast(Spkr, 128);
  */

  pwmtimer->pause();
  pwmtimer->setOverflow(31250, HERTZ_FORMAT); // calculate prescaler and overflow
  pwmtimer->setMode(3, TIMER_OUTPUT_COMPARE_PWM1, PB0); // TIM3 CH3 - PWM
  pwmtimer->attachInterrupt(irq_handler_timer3);        // attach interrupt on overflow
  pwmtimer->resume();


}

static void pwmWritefast(uint8_t pin, uint16_t duty_cycle)
{
  //timer_set_compare(PIN_MAP[pin].timer_device, PIN_MAP[pin].timer_channel, duty_cycle);
  pwmtimer->setCaptureCompare(3, duty_cycle, PERCENT_COMPARE_FORMAT); // Channel 3
}

There are two lines with

Code: Select all

//TIMER2_BASE->CR1  |= TIMER_CR1_CEN; 
that i just commented out (couldn't see anywhere else that timer 2 is needed).


Keep in mind that audio out is hardcoded to PB0 (Timer 3 , channel 3)

I tested it on STM32F103C8, with PB0 connected to small audio amplifier with low pass filter. There is a sound, but i tested only tune that is already in sketch. I didn't try convert midi.
Go to full post
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: MIDI file player?

Post by fpiSTM »

This project uses the LibMaple core so you will have to convert it to use the HardwareTimer from the STM2 core.
That's why you got those errors.
GVisser
Posts: 19
Joined: Thu Jun 11, 2020 5:17 pm
Answers: 1
Location: Hatfield, UK

Re: MIDI file player?

Post by GVisser »

fpiSTM wrote: Fri Jun 26, 2020 6:05 pm This project uses the LibMaple core so you will have to convert it to use the HardwareTimer from the STM2 core.
That's why you got those errors.
Hey @fpiSTM , thanks for that.

I'll see what I can do :-)
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: MIDI file player?

Post by ag123 »

midi is kind of the 'deep end' the usual things are to try to get a simple sketch e.g. blink working first to understand the platform.
libmaple has some f401 'support' but do be wary that the api is not consistent with F401 so you may still end up having to 'port' the app simply to run it on f401.
i'd guess midi can go from the easy monotone ones to very complicated polyphonic play with wave tables / sound fonts

for something simplier you may like to try rtttl
https://github.com/ponty/arduino-rtttl-player
i hacked one onto stm32f103 (maple mini) based libmaple core
https://github.com/ag88/stm32duino_rtttl
User avatar
Bakisha
Posts: 139
Joined: Fri Dec 20, 2019 6:50 pm
Answers: 5
Contact:

Re: MIDI file player?

Post by Bakisha »

Hi, i might help a little bit since once i did project with audio with PWM. After a quick look on a sketch, i changed few line, to be able to compile on official core:

Code: Select all

//HardwareTimer pwmtimer(3);
HardwareTimer *pwmtimer = new HardwareTimer(TIM3);

void PWM_Init( void )
{
  /*
    Timer3.attachCompare1Interrupt( irq_handler_timer3 ); // <-- this will set all the needed clokcks and int vectors
    pwmtimer.setPrescaleFactor(9);
    pwmtimer.setCount(0);
    pwmtimer.setOverflow(255);
    pinMode(Spkr, PWM);
    pwmWritefast(Spkr, 128);
  */

  pwmtimer->pause();
  pwmtimer->setOverflow(31250, HERTZ_FORMAT); // calculate prescaler and overflow
  pwmtimer->setMode(3, TIMER_OUTPUT_COMPARE_PWM1, PB0); // TIM3 CH3 - PWM
  pwmtimer->attachInterrupt(irq_handler_timer3);        // attach interrupt on overflow
  pwmtimer->resume();


}

static void pwmWritefast(uint8_t pin, uint16_t duty_cycle)
{
  //timer_set_compare(PIN_MAP[pin].timer_device, PIN_MAP[pin].timer_channel, duty_cycle);
  pwmtimer->setCaptureCompare(3, duty_cycle, PERCENT_COMPARE_FORMAT); // Channel 3
}

There are two lines with

Code: Select all

//TIMER2_BASE->CR1  |= TIMER_CR1_CEN; 
that i just commented out (couldn't see anywhere else that timer 2 is needed).


Keep in mind that audio out is hardcoded to PB0 (Timer 3 , channel 3)

I tested it on STM32F103C8, with PB0 connected to small audio amplifier with low pass filter. There is a sound, but i tested only tune that is already in sketch. I didn't try convert midi.
GVisser
Posts: 19
Joined: Thu Jun 11, 2020 5:17 pm
Answers: 1
Location: Hatfield, UK

Re: MIDI file player?

Post by GVisser »

ag123 wrote: Fri Jun 26, 2020 7:48 pm midi is kind of the 'deep end' the usual things are to try to get a simple sketch e.g. blink working first to understand the platform.
libmaple has some f401 'support' but do be wary that the api is not consistent with F401 so you may still end up having to 'port' the app simply to run it on f401.
i'd guess midi can go from the easy monotone ones to very complicated polyphonic play with wave tables / sound fonts

for something simplier you may like to try rtttl
https://github.com/ponty/arduino-rtttl-player
i hacked one onto stm32f103 (maple mini) based libmaple core
https://github.com/ag88/stm32duino_rtttl
Thanks @ag123 , I'll go take a look.
GVisser
Posts: 19
Joined: Thu Jun 11, 2020 5:17 pm
Answers: 1
Location: Hatfield, UK

Re: MIDI file player?

Post by GVisser »

Bakisha wrote: Fri Jun 26, 2020 9:18 pm Hi, i might help a little bit since once i did project with audio with PWM. After a quick look on a sketch, i changed few line, to be able to compile on official core:

Code: Select all

//HardwareTimer pwmtimer(3);
HardwareTimer *pwmtimer = new HardwareTimer(TIM3);

void PWM_Init( void )
{
  /*
    Timer3.attachCompare1Interrupt( irq_handler_timer3 ); // <-- this will set all the needed clokcks and int vectors
    pwmtimer.setPrescaleFactor(9);
    pwmtimer.setCount(0);
    pwmtimer.setOverflow(255);
    pinMode(Spkr, PWM);
    pwmWritefast(Spkr, 128);
  */

  pwmtimer->pause();
  pwmtimer->setOverflow(31250, HERTZ_FORMAT); // calculate prescaler and overflow
  pwmtimer->setMode(3, TIMER_OUTPUT_COMPARE_PWM1, PB0); // TIM3 CH3 - PWM
  pwmtimer->attachInterrupt(irq_handler_timer3);        // attach interrupt on overflow
  pwmtimer->resume();


}

static void pwmWritefast(uint8_t pin, uint16_t duty_cycle)
{
  //timer_set_compare(PIN_MAP[pin].timer_device, PIN_MAP[pin].timer_channel, duty_cycle);
  pwmtimer->setCaptureCompare(3, duty_cycle, PERCENT_COMPARE_FORMAT); // Channel 3
}

There are two lines with

Code: Select all

//TIMER2_BASE->CR1  |= TIMER_CR1_CEN; 
that i just commented out (couldn't see anywhere else that timer 2 is needed).


Keep in mind that audio out is hardcoded to PB0 (Timer 3 , channel 3)

I tested it on STM32F103C8, with PB0 connected to small audio amplifier with low pass filter. There is a sound, but i tested only tune that is already in sketch. I didn't try convert midi.
Wow @Bakisha , thank you VERY much for this! I'll give it a go and report back :-) Much much appreciated!

EDIT: Compiles perfectly :D Will get to do a physical test later :D Again, thank you very much!
GVisser
Posts: 19
Joined: Thu Jun 11, 2020 5:17 pm
Answers: 1
Location: Hatfield, UK

Re: MIDI file player?

Post by GVisser »

Hey @Bakisha ,

Completed the in-circuit test and it all works well, apart from one small change I had to make to the code 8-)

Strangely enough, setting the timer to

Code: Select all

TIMER_OUTPUT_COMPARE_PWM1
mode, caused the program to set the pin output HIGH in between tones with the tones pulling the output low:
PWM1.jpg
PWM1.jpg (59.13 KiB) Viewed 7027 times
Changing the mode with

Code: Select all

TIMER_OUTPUT_COMPARE_PWM2
, solved the problem:
PWM2.jpg
PWM2.jpg (62.87 KiB) Viewed 7027 times

I would have expected the opposite, but the code works nonetheless and I am a happy chap! :D

Again, my thanks and appreciation for your help!
Last edited by GVisser on Sun Jun 28, 2020 12:17 pm, edited 1 time in total.
GVisser
Posts: 19
Joined: Thu Jun 11, 2020 5:17 pm
Answers: 1
Location: Hatfield, UK

Re: MIDI file player?

Post by GVisser »

Bakisha wrote: Fri Jun 26, 2020 9:18 pm I tested it on STM32F103C8, with PB0 connected to small audio amplifier with low pass filter. There is a sound, but i tested only tune that is already in sketch. I didn't try convert midi.
Hey @Bakisha , quick question ... what did your test sound like? Was it clear or did it sound somewhat 'distorted'?

Mine is sounding distorted (at any volume) and I am not sure where it is coming from. If yours sounded fine, then it could be my procs clock speed and could thus mean that I would need to tweak the timer parameters. Single notes sound fine but the moment there are slightly more complex groups of notes, it 'distorts'. I will play with the code in the mean time but would really be interested to know what yours was like? :-)

ADDENDUM: Have now tried other midi files, adjusted the tempo and even some timer params but am still getting the same distortion with the chords, so maybe it is my circuit .... hmmmm
User avatar
Bakisha
Posts: 139
Joined: Fri Dec 20, 2019 6:50 pm
Answers: 5
Contact:

Re: MIDI file player?

Post by Bakisha »

@GVisser

After some experiment on my diy-dev board for audio experiments, here is my conclusions:
- Depending on what device you are connected, distortions are present when you are plugged in some equipment with AUDIO-IN. Most probably because it expect 1Vp-p, and you are feeding it with 3.3Vp-p.
Here is recommended audio setup:

Code: Select all

//  .-------------------------------------.
//  |                                     |
//  | STM32FxxxXXxx                       |
//  .---------------------------------|---.
//  |G                               P|
//  |N                               B|
//  |D                               0-----|R1|------|C2|----------|
//  |                                            |                 --
//  |                                            C                 || P1
//  |                                            1                 ||<----------------| OUDIO OUT
//  |                                            |                 --
//  .--------------------------------------------|-----------------|------------------| GND

//  R1 = 100-500 Ohm
//  C1 = 100-500 nF
//  C2 = 10 uF
//  P1 = 10KOhm potentiometer
Also, distortions may come from a way how author decided to create sound. Base PWM frequency of 31250Hz is, IMHO, just too low for 1-bit DAC.
maybe it's ok for 1 channel, but for four channels (used in sketch), it is noticeably full of "eeeeeks" :-)
Maybe try with higher capacitor in low-pass filter (500nF+), or higher resistor (500 Ohm+).
In my audio project, i used 250KHz base PWM frequency, that's 4uS period, meaning it is 4*72= 288 (bluepill) or 4*84=336 (STM32F401CC) values for width of that pulse. Enough for 3 channels (each channel is 1/3 of maximum of pulse width).
I think author just ported code for STM32, with all the limitation original code have (for arduino uno).

Also, i don't think it doesn't matter is it PWM1 or PWM2 mode. Beside visually in analyzer. Sound is difference in audio signal, it sound the same when you are altering between 99% HIGH - 1% LOW and 100% HIGH - 0% LOW, and 1% HIGH - 99% LOW and 100% LOW - 0% HIGH. It's the difference of 1% that is creating analog AC voltage.
Personally, i'm more into digital electronics then into analog. With digital, i'm dealing only with ones and zeroes :-)

Anyway,

Code: Select all

setOverflow(31250, HERTZ_FORMAT);
will set correct prescaler and overflow for you, no matter on what speed CPU is (and that's why i like this core: same code, no matter is it STM32F103C or STM32F401CC).
Post Reply

Return to “General discussion”