Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No sound - missing something? #19

Open
astwist opened this issue Nov 12, 2021 · 7 comments
Open

No sound - missing something? #19

astwist opened this issue Nov 12, 2021 · 7 comments

Comments

@astwist
Copy link

astwist commented Nov 12, 2021

Hello!
We are trying to run Nuked-OPN2 on a teensy MCU, everything appears to run OK but no sound.

We are first calling OPN2_Reset

then executing OPN2_Clock() inside our audio buffer,

We get noise at the output when manually updating mor and mol with random numbers inside of the PN2_ChOutput() function,
but no signal is generated by the emulator when we send the test code below (taken from the datasheet):

`ym3438.write(0x22, 0x00); // LFO off
ym3438.write(0x27, 0x00); // Note off (channel 0)
ym3438.write(0x28, 0x01); // Note off (channel 1)
ym3438.write(0x28, 0x02); // Note off (channel 2)
ym3438.write(0x28, 0x04); // Note off (channel 3)
ym3438.write(0x28, 0x05); // Note off (channel 4)
ym3438.write(0x28, 0x06); // Note off (channel 5)
ym3438.write(0x2B, 0x00); // DAC off
ym3438.write(0x30, 0x71); //
ym3438.write(0x34, 0x0D); //
ym3438.write(0x38, 0x33); //
ym3438.write(0x3C, 0x01); // DT1/MUL
ym3438.write(0x40, 0x23); //
ym3438.write(0x44, 0x2D); //
ym3438.write(0x48, 0x26); //
ym3438.write(0x4C, 0x00); // Total level
ym3438.write(0x50, 0x5F); //
ym3438.write(0x54, 0x99); //
ym3438.write(0x58, 0x5F); //
ym3438.write(0x5C, 0x94); // RS/AR
ym3438.write(0x60, 0x05); //
ym3438.write(0x64, 0x05); //
ym3438.write(0x68, 0x05); //
ym3438.write(0x6C, 0x07); // AM/D1R
ym3438.write(0x70, 0x02); //
ym3438.write(0x74, 0x02); //
ym3438.write(0x78, 0x02); //
ym3438.write(0x7C, 0x02); // D2R
ym3438.write(0x80, 0x11); //
ym3438.write(0x84, 0x11); //
ym3438.write(0x88, 0x11); //
ym3438.write(0x8C, 0xA6); // D1L/RR
ym3438.write(0x90, 0x00); //
ym3438.write(0x94, 0x00); //
ym3438.write(0x98, 0x00); //
ym3438.write(0x9C, 0x00); // Proprietary
ym3438.write(0xB0, 0x32); // Feedback/algorithm
ym3438.write(0xB4, 0xC0); // Both speakers on
ym3438.write(0x28, 0x00); // Key off
ym3438.write(0xA4, 0x22); //
ym3438.write(0xA0, 0x69); // Set frequency

while(1){
ym3438.write(0x28, 0xC0); //key on
delay(1000);
ym3438.write(0x28, 0); //key off
delay(1000);
}`

I have a doubts about the following functions:
OPN2_SetTestPin
OPN2_SetChipType
Must they be called to enable signal generation?
Anything else we are missing?
Thanks in advance!
Cheers
Alex

@nukeykt
Copy link
Owner

nukeykt commented Nov 12, 2021

Do you call OPN2_Clock between OPN2_Write calls? YM3438 requires some delays between writes to process data correctly and Nuked OPN2 emulates this behaviour.

@dcoredump
Copy link

Thanks for the fast answer!

I tried to add a delay(100); inside the write()-wrapper:

void write(Bit32u port, Bit8u data)
    {   
        OPN2_Write(&chip, port, data);
        delay(100);
    }

But the output of the buffers is again 0.

I have to note that we are currently have no resampler-code added, but I am looking at the signal sum to see if something happens.

@Wohlstand
Copy link
Contributor

Nope, this won't work, The emulator isn't asynchronous, because you do iterate its work by yourself. You should tick it to make it being iterated.,

@Wohlstand
Copy link
Contributor

here is an example of how that worked: https://github.com/Wohlstand/libOPNMIDI/blob/master/src/chips/nuked/ym3438.c#L1473-L1506
also, my fork of an emulator (linked here) has simplified calls that do all jobs for you if you want to have the simple processing with register data writing and PCM output after the process. Otherwise, the emulator needs to work with it using almost the same logic as with the hardware chip.

@dcoredump
Copy link

Thanks @Wohlstand!

We tried your code (mentioned inside the other thread, which I will close soon) with buffered write and resampler, but this code has problems with the Teensy audio stack when enabling the audio interrupts. It seems that the calculation of the sound eats up all CPU time. This is strange, because I have a running Dexed (with 2 * 16 voices * 6 OPs each voice = 192 OPs + envelopes) running on the same type of microcontroller.

This happens only when trying the resampler code with buffered write. The original code does not have this problem (apart from our write() problems). I think I have to go deeper into the engine to find the solution of those problems.

Do you have any other hints?

@Wohlstand
Copy link
Contributor

Wohlstand commented Nov 12, 2021

Nuked OPN2 emulator is heavy by itself because it implements the chip very accurately. All internals of WriteBuffered and GenerateRsampled implement the logic to deal with the chip. Without these codes, you need to repeat the almost same work as these calls do. Your write() problems resulted in the chip wasn't iterated properly at all, it was just idling, because you didn't call the OPN2_Clock() that executes the chip's processing step. So, how that should be used actually without buffered and resampled calls:

  • OPN2_Clock() - to process one cycle of the chip
  • OPN2_Write() - to write the data

Also, the data writing here is different than you expected: you need to call it multiple times to send register value first, and then, value itself. So, to send one value into one address, you need to call OPN2_Write() twice.

@dcoredump
Copy link

Thanks @nukeykt and @Wohlstand!

I have now managed to successfully write data to the registers. Now I have to see if I can get the downsampling from 53267 Hz to 44100 Hz somehow.

Wouldn't it also be possible to tell the library that it should no longer start from a system clock of 7670454 Hz, but from 44100 / 53267 * 7670454 = 6350405 Hz?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants