It is currently Sat Oct 21, 2017 1:45 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 37 posts ]  Go to page 1, 2, 3  Next
Author Message
PostPosted: Mon Aug 18, 2014 9:45 pm 
Offline
User avatar

Joined: Sat May 31, 2014 4:12 pm
Posts: 139
Hello everyone,

I have never used the DPCM channel before but I would like to. Using FamiTracker, I have uploaded samples and used them and it worked fine but never used them in an actual game. How do I introduce those samples into the game itself? All the other tracks for the game are complete except the DPCM.

-Ray


Top
 Profile  
 
PostPosted: Mon Aug 18, 2014 10:32 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6289
Location: Seattle
You'll need to provide a few more details before we can give you a useful answer.


Top
 Profile  
 
PostPosted: Mon Aug 18, 2014 11:50 pm 
Offline
User avatar

Joined: Sat May 31, 2014 4:12 pm
Posts: 139
Not sure what details you'll need me to provide.


Top
 Profile  
 
PostPosted: Tue Aug 19, 2014 12:34 am 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6289
Location: Seattle
How much of a game do you have? What do you already understand?
Have you already tried making a very simple ROM that just plays a DPCM sample?
What music playback engine are you using?


Top
 Profile  
 
PostPosted: Tue Aug 19, 2014 1:16 am 
Offline
User avatar

Joined: Fri Jan 24, 2014 9:05 am
Posts: 132
Location: Hungary
Implementing DPCM *could* be the easiest thing to do if it wasn't for the controller port/PPU data reading bugs introduced (of which you probably only need to worry about the former)
But playing a DPCM sample by itself is incredibly easy.
First I advise turning it off by writing $0F to $4015
You simply need to target the starting point with the register $4012. The starting points are aligned to a 64 byte grid, and you can only play samples from CPU address $C000-$FFFF (which is usually the last 16k or PRG ROM)

This means you can only start a sample from $C000, $C040, $C080...

Then you specify the length of the sample in 16 byte increments by writing a value to $4013
You also need to choose a playback pitch by writing $00-$0F to $4010.
Then you re-enable the channel to start the automated playback by writing $1F to $4015.

You may optionally include a write to $4011 to set the DC offset to a known value, but this makes a pop (in famitracker this is basically a Zxx)


Top
 Profile  
 
PostPosted: Tue Aug 19, 2014 4:34 pm 
Offline
User avatar

Joined: Sat May 31, 2014 4:12 pm
Posts: 139
Just to confirm I understand:

If I write the value $03 to $4012, what that will do is instruct the DPCM channel to start reading at $C0B0 (is this correct?). It won't actually play the sounds until I enable the DPCM channel by setting the bit4 to 1 in $4015, which can be accomplished by writing the value $1F to $4015 hence enabling all five sound channels. If I wish to have the DPCM channel play a sound sample that is, say, 32 bytes long, then I would write the value $02 to $4013. (or would i write the value $01 to $4013?) Then I would write between $00-$0F to 4010 for the pitch adjustment.

I take it that the maximum length for a DPCM sample is 4096 bytes?

NEW QUESTIONS:
1) How do I convert a .wav file into a series of bytes that the program will read?
2) Once converted to a series of bytes, do I introduce them into the program as a database like this?
Song:
.db $5F, $00, $37, $3B, etc.
Would I really have to type into my program up to 4096 bytes per sample all by hand?


Top
 Profile  
 
PostPosted: Tue Aug 19, 2014 4:58 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19113
Location: NE Indiana, USA (NTSC)
raydempsey wrote:
Just to confirm I understand:

If I write the value $03 to $4012, what that will do is instruct the DPCM channel to start reading at $C0B0 (is this correct?).

$C0C0

Quote:
If I wish to have the DPCM channel play a sound sample that is, say, 32 bytes long, then I would write the value $02 to $4013. (or would i write the value $01 to $4013?)

$01 produces 17 bytes, and $02 produces 33 bytes.

Quote:
Then I would write between $00-$0F to 4010 for the pitch adjustment.

The typical order of writes is $4010, $4012, $4013.

Quote:
I take it that the maximum length for a DPCM sample is 4096 bytes?

Correct. But you're not going to have a lot of them without a mapper that can bankswitch $C000-$DFFF, such as MMC3 or FME-7. If you have a lot of samples and little else that needs to be accessed while a sample is playing, you could try upside-down UNROM (#180) or MMC1.

Quote:
How do I convert a .wav file into a series of bytes that the program will read?

A long time ago, I made such a conversion tool.

Quote:
Once converted to a series of bytes, do I introduce them into the program as a database like this?

It depends on the assembler, but most assemblers have something paralleling ca65's .incbin.
Code:
  .align 64
kickdrum:
  .incbin "kickdrum.dmc"
kickdrum_end:

  .align 64
snaredrum:
  .incbin "snaredrum.dmc"
snaredrum_end:

Then you calculate the values to write to $4012 and $4013 like this, assuming your assembler handles bit shifts in expressions:
Code:
  lda #<(kickdrum >> 6)
  sta $4012
  lda #<((kickdrum_end - kickdrum) >> 4)
  sta $4013


Top
 Profile  
 
PostPosted: Tue Aug 19, 2014 9:38 pm 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2962
Location: Tampere, Finland
raydempsey wrote:
do I introduce them into the program as a database like this?
Song:
.db $5F, $00, $37, $3B, etc.

".db" doesn't stand for database, it more likely originates from "define byte".

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Thu Sep 04, 2014 10:29 am 
Offline
User avatar

Joined: Sat May 31, 2014 4:12 pm
Posts: 139
Hello again,

Here is my new set of DPCM questions:

After importing .wav files in FamiTracker for use as DPCM samples, I implemented them into my FamiTracker song and I am now trying to implement them into my NES game. In Files > Export Text of FamiTracker, it exports a .txt file that has byte information regarding my song. The .txt file I posted here is modified to show a single sample's byte information. I was told that somehow I could incorporate this byte information into my game using some .incbin method which I am absolutely unfamiliar with. I am using NESASM3 as my assembler not ca65.

Question 1: How do I use the byte information as attached in the .txt file into my program?

Question 2: What is the complete process that you do to take a .wav file and implement it into your game under the DPCM channel? The only conversion of a .wav file I know of is through FamiTracker. The program from the link to the conversion tool provided earlier did not run for me.
tepples wrote:
A long time ago, I made such a conversion tool.


Question 3: As for pitch adjustment (writing $00 - $0F to $4010), what write keeps the .wav file the same pitch? Can the pitch be adjusted both up and down?

I believe it would be possible and very very unnecessarily time consuming to manually type into my program my DPCM byte information for all of my samples by .db but I don't want to do that for a few reasons. First, it would take forever considering each sample could be as long as 4096 bytes. Second, when writing the location of the sample to $4012, that location may change if I otherwise alter my program and hence anytime I make a change to the program, I would have to observe the new location of the start of each sample and obviously that is not the most efficient way to do things.

Thanks everybody.
-Ray


Attachments:
DPCM from FamiTracker.txt [11.92 KiB]
Downloaded 55 times
Top
 Profile  
 
PostPosted: Thu Sep 04, 2014 10:47 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19113
Location: NE Indiana, USA (NTSC)
raydempsey wrote:
What is the complete process that you do to take a .wav file and implement it into your game under the DPCM channel?

Here are the steps I use, assuming use of ca65/ld65:
  1. Convert it through my tool.
  2. Use .segment "DPCM" to make sure that all samples end up in $C000-$FFF1.
  3. Ensure that the link script contains an appropriate assignment for that segment.
  4. Use .align 64 to make sure that each included sample begins on a 64-byte boundary, as required by $4012.
  5. Add the converted sample as a binary file using .incbin.
  6. Add labels before and after the sample.
  7. Create a lookup table containing the values to be written to $4012 and $4013 for each sample, computed from the labels. The start is .byte <(fourlines_dmc >> 6), and the length is .byte <((fourlines_dmc_end - fourlines_dmc) >> 4).
For a complete working example, please see the Eighty demo. (It was originally a test of the NES Four Score accessory, and you will need an NES Four Score accessory, NES Satellite accessory, or emulator supporting one of those accessories in order to run it.)

Quote:
The only conversion of a .wav file I know of is through FamiTracker. The program from the link to the conversion tool provided earlier did not run for me.

Did you run it from the command prompt, or did you double-click it in Windows Explorer? If you double-clicked it in Windows Explorer, it probably opened a black window that immediately closed. Please run it from the command prompt instead. If you ran it from the command prompt, what error message did it display?

Quote:
As for pitch adjustment (writing $00 - $0F to $4010), what write keeps the .wav file the same pitch?

Before converting the sample, use Audacity or another audio editor to resample the file to one of the supported sample rates listed on the wiki page.

Quote:
Can the pitch be adjusted both up and down?

I think my older tool can only resample up.


Top
 Profile  
 
PostPosted: Thu Sep 04, 2014 10:50 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5728
Location: Canada
Why would you have to type your DPCM bytes in by hand? Why not write a short script/program to read that .txt file and reformat it into .db or whatever you need?

Alternatively, you can also save the DPCM sample from Famitracker as a binary file (click the "save" button in the DPCM panel of the instrument editor). This file can simply be included as a binary in your assembly program.


Top
 Profile  
 
PostPosted: Thu Sep 04, 2014 11:52 am 
Offline
User avatar

Joined: Sat May 31, 2014 4:12 pm
Posts: 139
Just as a continual warning, I do not have nearly as much computer science experience as you guys do so thank you for your patience.

tepples wrote:
Here are the steps I use, assuming use of ca65/ld65:
Convert it through my tool.
Use .segment "DPCM" to make sure that all samples end up in $C000-$FFF1.
Ensure that the link script contains an appropriate assignment for that segment.
Use .align 64 to make sure that each included sample begins on a 64-byte boundary, as required by $4012.
Add the converted sample as a binary file using .incbin.
Add labels before and after the sample.
Create a lookup table containing the values to be written to $4012 and $4013 for each sample, computed from the labels. The start is .byte <(fourlines_dmc >> 6), and the length is .byte <((fourlines_dmc_end - fourlines_dmc) >> 4).

I am using only the NESASM3 assembler so the method you are using would have to be altered to some NESASM3 equivalent which I am unaware of.

Also, I got the conversion tool running (81.exe) and this is what I saw:
81 by Damian Yerrick: compresses pcm wav file to 8ad
usage: 81 infile outfile [upsample_pct [amplitude]]
example: 81 song.wav song.dcm 100 24

Not sure how to convert the .wav file from here. Do I put the file in the same folder as 81.exe? Do I have to rename the .wav file before I start the process? I did both of those and so far I think that nothing happened.

tepples wrote:
Alternatively, you can also save the DPCM sample from Famitracker as a binary file (click the "save" button in the DPCM panel of the instrument editor). This file can simply be included as a binary in your assembly program.

I was able to successfully save a sample as .dmc from the FamiTracker DPCM in the instrument editor. I assume I can include it by the following line in my program:
.incbin "sample.dmc"
I already have a .incbin "graphix.chr" which works just fine. Does the assembler know from the file extension that the .chr is CHR info and .dmc is sample info? Can I just use this method instead of conversion through 81.exe?


Top
 Profile  
 
PostPosted: Thu Sep 04, 2014 12:39 pm 
Offline
User avatar

Joined: Mon Feb 07, 2011 12:46 pm
Posts: 928
raydempsey wrote:
tepples wrote:
Here are the steps I use, assuming use of ca65/ld65:
Convert it through my tool.
Use .segment "DPCM" to make sure that all samples end up in $C000-$FFF1.
Ensure that the link script contains an appropriate assignment for that segment.
Use .align 64 to make sure that each included sample begins on a 64-byte boundary, as required by $4012.
Add the converted sample as a binary file using .incbin.
Add labels before and after the sample.
Create a lookup table containing the values to be written to $4012 and $4013 for each sample, computed from the labels. The start is .byte <(fourlines_dmc >> 6), and the length is .byte <((fourlines_dmc_end - fourlines_dmc) >> 4).

I am using only the NESASM3 assembler so the method you are using would have to be altered to some NESASM3 equivalent which I am unaware of.
NESASM doesn't use link script, and there are no segments. Instead you use bank and org to set the address. The lookup tables would then look like db low(fourlines_dmc >> 6) and db low((fourlines_dmc_end - fourlines_dmc) >> 4). To do alignment, you would do it like this: ds (64-*)&63

Quote:
Also, I got the conversion tool running (81.exe) and this is what I saw:
81 by Damian Yerrick: compresses pcm wav file to 8ad
usage: 81 infile outfile [upsample_pct [amplitude]]
example: 81 song.wav song.dcm 100 24

Not sure how to convert the .wav file from here. Do I put the file in the same folder as 81.exe? Do I have to rename the .wav file before I start the process? I did both of those and so far I think that nothing happened.
You need to type 81 followed by the name of the input file and then the name of the output file. (If you are using Windows Explorer, start by pushing Windows Logo key + R (simultaneously), type in "cmd" and then at the prompt, type in "cd" and a space and drag the folder icon into the command window; this will select the directory it is in. And then you can do the same for the files, or just type them in yourself.

Quote:
tepples wrote:
Alternatively, you can also save the DPCM sample from Famitracker as a binary file (click the "save" button in the DPCM panel of the instrument editor). This file can simply be included as a binary in your assembly program.

I was able to successfully save a sample as .dmc from the FamiTracker DPCM in the instrument editor. I assume I can include it by the following line in my program:
.incbin "sample.dmc"
I already have a .incbin "graphix.chr" which works just fine. Does the assembler know from the file extension that the .chr is CHR info and .dmc is sample info? Can I just use this method instead of conversion through 81.exe?
You need to select the correct bank/address to place the data in; it won't know just from the file extension. Since you are using NESASM, this is done by typing bank and then the bank number, in terms of 8K banks. The iNES header is in terms of 16K PRG banks and 8K CHR banks, so the first CHR bank will be twice the number of PRG banks (so for NROM-256, use bank 4 for CHR ROM).

_________________
.


Top
 Profile  
 
PostPosted: Thu Sep 04, 2014 12:42 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5728
Location: Canada
The assembler does not know anything about CHR or DPCM data. The .incbin directive merely includes a binary file directly into the assembled code, meaning every byte that is in the file gets dumped into your assembled binary at that point you wrote .incbin. The file extension is irrelevant; you can .incbin any file type.

If you put proper DPCM data at the right location, and tell the NES to play it correctly, it will play. If you put CHR data at the right location, the NES will render it. The assembler is merely placing data in a file for you.


Top
 Profile  
 
PostPosted: Thu Sep 04, 2014 3:54 pm 
Offline
User avatar

Joined: Sat May 31, 2014 4:12 pm
Posts: 139
raydempsey wrote:
You need to select the correct bank/address to place the data in; it won't know just from the file extension. Since you are using NESASM, this is done by typing bank and then the bank number, in terms of 8K banks. The iNES header is in terms of 16K PRG banks and 8K CHR banks, so the first CHR bank will be twice the number of PRG banks (so for NROM-256, use bank 4 for CHR ROM).

QUESTION 1:
Being that this is my first game, I used a tutorial program and erased all but the starting info based on their settings so I never understood the part involving .bank and .org. Let me know if I have this right: If a person has this in their code:
Code:
.bank 0
.org $C000

then the following code in the program will be stored there until another one is typed later on:
Code:
.bank 1
.org $E000

then the code from that point on will be stored there?

QUESTION 2:
In my code, at the very end is written:
Code:
.bank 2
.org $0000
.incbin "tiles.chr"

which successfully implements the 8K of tiles into the game by saving the binary information into the PPU. The question I have is: how come in my .bank 0 and .bank 1 examples, the assembler knows to save the code into the respective locations in the CPU but in the .bank 2 example the assembler knows to save the data in the PPU?

QUESTION 3:
Can I write any address after .org or must it be some multiple of $1000?

QUESTION 4:
Why must the .bank part be there? Is that something I'll utilize when it's time to do some bank switching?

Another thing: Here is my NESASM3 beginning config I've been using just in case it's important.
Code:
  .inesprg 1   ; 1x 16KB PRG code
  .ineschr 1   ; 1x  8KB CHR data
  .inesmap 119


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 37 posts ]  Go to page 1, 2, 3  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group