FamiStudio NES Sound Engine (famiStudio) 2.2 in C

Discuss NSF files, FamiTracker, MML tools, or anything else related to NES music.

Moderator: Moderators

Post Reply
dienben2020
Posts: 24
Joined: Wed Sep 30, 2020 2:19 pm

FamiStudio NES Sound Engine (famiStudio) 2.2 in C

Post by dienben2020 » Wed Sep 30, 2020 2:40 pm

Hi,

First, thank you very much for the FamiStudio 2.2 I'm sorry if the following questions are very basic.

I'm trying to integrate the FamiStudio NES Sound Engine in a C pipeline. I'm following the information from https://nesdoug.com/ , I'm able to create my 'own' game and would like to add music and SFX using FamiStudio NES Sound Engine.

I'm on MAC, using ca65.

I've first remove the famitone2.s file, include the sound engine (ca65) in what I think is my main assembly file (crt0.s), include some music from the demo, change the flag to external definition in the engine, it's compiling but I've got an error during the link (error that doesn't prevent the game to run by the way): ld65: Error: Missing memory area assignment for segment 'RAM'

I suppose it's because I've not well define the following part:

; CA65-specifc config.
.define FAMISTUDIO_CA65_ZP_SEGMENT ZEROPAGE
.define FAMISTUDIO_CA65_RAM_SEGMENT RAM
.define FAMISTUDIO_CA65_CODE_SEGMENT CODE

But I have no idea (sorry for that), to a way to fix it....

What exactly does it represent?(again sorry).

Additionnaly, I need to expose the following method to directly call them from my code:
  • famistudio_init
  • famistudio_music_play
  • famistudio_music_pause
  • famistudio_music_stop
  • famistudio_sfx_init
  • famistudio_sfx_play
  • famistudio_sfx_sample_play
  • famistudio_update
But it's another story (probably a combo export and fast call).

Regards,

Ben

User avatar
Memblers
Site Admin
Posts: 3889
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: FamiStudio NES Sound Engine (famiStudio) 2.2 in C

Post by Memblers » Wed Sep 30, 2020 3:28 pm

The linker uses "memory areas" and "segments". You put your code/data into segments, and the linker uses the config file you supply it with to output your stuff into the memory areas.

My guess about the error is because "RAM" is the name of a memory area, and not a segment. We'd need to see the .cfg file to be certain. If that's the case, find the segment that is assigned to RAM, and use that. And that's probably "BSS". So try replacing that line with:
.define FAMISTUDIO_CA65_RAM_SEGMENT BSS

More info about linker config here:
https://timcheeseman.com/nesdev/2016/01 ... t-two.html

User avatar
bleubleu
Posts: 101
Joined: Wed Apr 04, 2018 7:29 pm
Location: Montreal, Canada

Re: FamiStudio NES Sound Engine (famiStudio) 2.2 in C

Post by bleubleu » Wed Sep 30, 2020 8:00 pm

Hi!

Sorry i wasn't checking the forums for a few days. Did you figure it out?
If not, please reply, of maybe jump in the FamiStudio discord so we can chat about it (https://discord.gg/88UPmxh).

-Mat

dienben2020
Posts: 24
Joined: Wed Sep 30, 2020 2:19 pm

Re: FamiStudio NES Sound Engine (famiStudio) 2.2 in C

Post by dienben2020 » Thu Oct 01, 2020 11:10 pm

Hi,

Thank you very much memblers for your answer. I'm working to have a better understanding of my Setup using your link. Basically, I'm trying to replace the Famitone2 by the Famistudio lib in the nesdoug lib. I'm preparing a better synthesis and come back to you!

@bleubleu: thanks again for famistudio!!

Regards,

Ben

dienben2020
Posts: 24
Joined: Wed Sep 30, 2020 2:19 pm

Re: FamiStudio NES Sound Engine (famiStudio) 2.2 in C

Post by dienben2020 » Sat Oct 03, 2020 7:08 am

Hello,

Sorry to come back without solution but I'm blocked, probably because I'm not fully understanding the NES programming yet :oops: .

I've create a repository to help: https://bitbucket.org/bfoucque/dien-fam ... rc/master/

This repository is dedicated to the integration of the famistudio library in the neslib nesdoug C ecosystem

Objectives
  • Natively integrate the famistudio engine in C project
  • Provide project template
  • Provide how to
Project Description
There is two directories: dienmusic and dienpong

Dienpong
Dienpong is a fully functional Pong like game.
Image

  • UP or DOWN to move their sorcerers
  • START will start a round or pause - unpause the game
  • LEFT - RIGHT pushed during rebound throw the ball up or down
  • B pushed accelerate the player during 3 seconds, consuming a star
  • A pushed during rebound accelerate the ball but consummes a star
  • a star is won every 3 rebound

So it's fairly simple ;-)

The code has several options (wall rebound etc...). The game is running on both emulators and hardware.

Dienmusic
It is dienpong but with a try to:
  • remove the famitone function
  • add the famistudio engine
  • create a famistudio.h in order to expose the functions (sorry if it's a mistake)
  • famistudio lib setup in the .s
Current issue
I get the following error: LIB/famistudio.s(773): Error: Range error ....
Image

Who do I talk to?
Any person who would like to help :-)

User avatar
Memblers
Site Admin
Posts: 3889
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: FamiStudio NES Sound Engine (famiStudio) 2.2 in C

Post by Memblers » Sat Oct 03, 2020 8:43 pm

The lines with the range error all have (indirect),y addressing mode. I think this means the variable is not being used as a zeropage address. Other lines accessing that variable aren't a problem because they can use absolute mode. The (indirect),y lines that it didn't complain about are inside an IF block, so they weren't being evaluated.

I found the problem. Similar to the last problem, ZP is the name of a memory area, ZEROPAGE is the name of the segment.

Code: Select all

MEMORY {
#RAM Addresses:
    # Zero page
    ZP: start = $00, size = $100, type = rw, define = yes;
---

SEGMENTS {
    ZEROPAGE: load = ZP,             type = zp;
---

.define FAMISTUDIO_CA65_ZP_SEGMENT   ZP
--
.segment .string(FAMISTUDIO_CA65_ZP_SEGMENT)
famistudio_ptr0: .res 2
---
@music_data_ptr = famistudio_ptr0
---
 lda (@music_data_ptr),y ; range error
 
change to:
.define FAMISTUDIO_CA65_ZP_SEGMENT ZEROPAGE

That should fix it!

dienben2020
Posts: 24
Joined: Wed Sep 30, 2020 2:19 pm

Re: FamiStudio NES Sound Engine (famiStudio) 2.2 in C

Post by dienben2020 » Sun Oct 04, 2020 12:35 pm

Hi,

Thanks a lot! I finally manage to use the famistudio engine in C. I working on the SFX. I've pushed the code but I will clean it (as soon as the fx will work) and push the template.

Regards,

Ben

dienben2020
Posts: 24
Joined: Wed Sep 30, 2020 2:19 pm

Re: FamiStudio NES Sound Engine (famiStudio) 2.2 in C

Post by dienben2020 » Tue Oct 06, 2020 1:14 pm

Hi,

Sorry to bother you again. I've push my last update (https://bitbucket.org/bfoucque/dien-fam ... rc/master/ directory dienmusic). If you unpause the game (START button), the music is playing. But when you push SELECT, normally I must play a SFX.

I've loaded the SFX from the sample, I hope that I've not made a mistake, but no crash and no sound.

In order to debug I get an old debugger on Mac and update it, but I don't

My guesses:
  • I could have not loaded the sfx properly (segment etc...)
  • Perhaps I do not update properly the engin (honnestly I'm trying to find where the music update is and I'm lost)
  • I could have missed a flag
  • ...
How can I debug? I'm currently installing a VM on my mac and try to compile mesen under linux, but I fail (Ubuntu)....

Regards,

Ben

User avatar
Memblers
Site Admin
Posts: 3889
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: FamiStudio NES Sound Engine (famiStudio) 2.2 in C

Post by Memblers » Tue Oct 06, 2020 6:30 pm

For a debugger you might try NESICIDE. 8bitworkshop might work for that, too (it's a little tricky to link with it, there's info on the forum about it though).

Looking at the source, I'm not sure where the NMI gets enabled. It is calling the audio update from NMI, which is correct. There's potentially a problem if an NMI interrupts the initializing of sfx/music. It depends on what the music engine does in that case, I'm not familiar at all with FamiStudio yet. There is this line commented out that might be relevant, I suppose the different threads would be the main loop and NMI.

Code: Select all

; Must be enabled if you are calling sound effects from a different thread than the sound engine update.
; FAMISTUDIO_CFG_THREAD         = 1     

dienben2020
Posts: 24
Joined: Wed Sep 30, 2020 2:19 pm

Re: FamiStudio NES Sound Engine (famiStudio) 2.2 in C

Post by dienben2020 » Wed Oct 07, 2020 1:12 pm

Hi,

Thanks for your answer.

I've got music, so I think I correctly calling the update function.

I'm new for the NES development (sorry for that) but I've added the famistudio update in the neslib file, at the end of the nmi (or what I thik is the end of the nmi ):
Image

When I'm changing the location of the call, I observe stange behavioir: the music is accelerated (NTSC/PAL) or the top of the screen is not correctly updated....

I think it's probably linked to the way I'm loading the data of the SFX, or something related to the setup...

For the debugger, I've not tried NESICIDE yet. I've just downloaded a Mac release, but I need to create a project and learn how to use it... next task now. I don't know if I could use C code or assembler only.

Regards,

Benoit

dienben2020
Posts: 24
Joined: Wed Sep 30, 2020 2:19 pm

Re: FamiStudio NES Sound Engine (famiStudio) 2.2 in C

Post by dienben2020 » Fri Oct 09, 2020 4:15 am

Hello,

I'm trying to understand what I am doing for the load of the SFX. Please, do not beat the one that try to understand how a 8bit system works during the night :lol:

I'm comparing my code and the demo_ca_63.s from Famistudio engine.

First focusing on the init: (demo_ca_63.s line 501)

Code: Select all

	; Load SFX
	ldx #<sounds
	ldy #>sounds
	jsr famistudio_sfx_init
 
sounds comes from (I think :oops: ) the
(line 749): inside segment "SONG 1" line 745

Code: Select all

sfx_data:
	.include "sfx_ca65.s"
which is then linked inside the sfx_ca65.s to the 2 sounds that I want to play.
SONG 1 is a segment, type ro (read only) indise the memory SONG 1: start = $a000, size = $2000, type = ro, file = %O, fill = yes, fillval = $ff;
I understand (but please correct me) that the segment will be pushed in memory, starting at $a000, we push all the data, then we complet with $ff value until reaching the $2000 lenght

In my case:
(file crt0.s)

Code: Select all

	ldx #<sounds
	ldy #>sounds
	jsr famistudio_sfx_init
sounds come from sounds_data, from the same file (different project location)
(file crt0.s line 267)

Code: Select all

; sounds_data:
sounds_data:
	.include "SFX/sfx_ca65.s"
sounds_data are inside segment RODATA, type ro: RODATA: load = PRG, type = ro, define = yes;
PRG: PRG: start = $8000, size = $8000, file = %O ,fill = yes, define = yes;

A detail: songs are loaded in the same memory and songs works....

Do you see any error?

Then we play:
In the demo (line 573)

Code: Select all

	lda #0
        ldx #FAMISTUDIO_SFX_CH0
        jsr famistudio_sfx_play
In my code (after compilation so dienmusic.s line 1906)

Code: Select all

L067F:	lda     #$00
	jsr     pusha
	lda     #$01
	jsr     _famistudio_sfx_play
Bref, I'm lost....

Could you help me? Or give a direction?

Again, thanks a lot for your time and patience.

Regards,

Benoit

dienben2020
Posts: 24
Joined: Wed Sep 30, 2020 2:19 pm

Re: FamiStudio NES Sound Engine (famiStudio) 2.2 in C

Post by dienben2020 » Mon Oct 12, 2020 1:47 pm

Hello,

I progress, I'm able to play a sound FX!!!!!

So, first, the code:
(dienmusic.c line )

Code: Select all

if((pad1_new & PAD_SELECT)||(pad2_new & PAD_SELECT))
		{
			//famistudio_sfx_play(0,0);
			asm("	lda #1 \n 	ldx #0 \n	jsr _famistudio_sfx_play \n	"	);
		}
The difference is in the ASM code generated. When I force the asm, I got:

Assembler code after compilation
(dienmusic.s line 1908)

Code: Select all

; asm(" lda #1 \n  ldx #0 \n jsr _famistudio_sfx_play \n " );
;
L0680:	lda     #1 
	ldx     #0 
	jsr     _famistudio_sfx_play 
	
But if i use the famistudio_sfx_play(0,0); (so uncommenting the code and commenting asm), I got:
(dienmusic.s line 1908)

Code: Select all

;
; famistudio_sfx_play(0,0);
;
L0681:	lda     #$00
	jsr     pusha
	jsr     _famistudio_sfx_play
Not the same code.... What I've missed? My declaration in C (famistudio.h):

Code: Select all

//play FamiTone sound effect on channel 0..3

void __fastcall__ famistudio_sfx_play(unsigned char sound,unsigned char channel);
The source code in dienmusic directory: https://bitbucket.org/bfoucque/dien-fam ... rc/master/

Regards,

Ben

dienben2020
Posts: 24
Joined: Wed Sep 30, 2020 2:19 pm

Re: FamiStudio NES Sound Engine (famiStudio) 2.2 in C

Post by dienben2020 » Tue Oct 13, 2020 2:00 pm

Hello,

The journey is nearly at its end :D

I'm able to play song (from famistudio), SFX, DPCM (with a behavior that I'm trying to explain but I got a lead) from C code. See sample in the repository....

I will write a small tutorial and release the source code (but you have nearly everything in the code) .

Regards,

Ben

Post Reply