It is currently Fri Nov 24, 2017 7:17 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 12 posts ] 
Author Message
PostPosted: Tue Aug 25, 2015 6:50 am 
Offline
Formerly AlienX
User avatar

Joined: Fri Apr 18, 2014 7:41 am
Posts: 133
Location: Bulgaria
I have encountered an interesting problem in Famitracker, when using DPCM samples. I made a thread about it on the Famitracker forum, but nobody replied, so I'm hoping somebody here can help.

I would like to use some DPCM bass for some of my projects. I want the samples to be really small, so I can have more space for drum and maybe sound effect samples and fit it all in the 16KB space, dedicated to DPCM data. So I made a bunch of Saw Wave samples for different notes. Each one is short and small. The way I would play longer notes is by looping them. And here is where I ran into an issue. When they loop, the samples sound like arpeggios are being used or something. As if there is some silence either in the beginning or the end of the sample, which ruins the clear sounding of the loop. And when creating those samples, I made sure they sound clear, when looping.

When I looked at the waveform in Famitracker, I noticed this:
Image
The compression has changed the beginning and ending of the wave. Is there a way to prevent this from happening? If I try using a sample with one wave cycle, this problem doesn't appear, but the pitch gets changed and every sample sounds like the same note. Perhaps the current length of the samples I'm using isn't right. If so, can someone tell me how long is the selection I've made in the screenshot and will this solve the problem with the looping?

I've included an FTM with one of the samples and the original .wav file.


Attachments:
DPCM Loop.zip [5.71 KiB]
Downloaded 59 times

_________________
Greetings! I'm That Bio Mechanical Dude and I like creating various stuff like movies, games and of course chiptunes!
You can check out my YouTube Channel.
You can also follow me on Twitter.
Top
 Profile  
 
PostPosted: Tue Aug 25, 2015 8:18 am 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2981
Location: Tampere, Finland
The DPCM sample length (in bytes) has to be of form 16*n+1 (where n=0, 1, 2, ..., 255). Most likely FamiTracker is padding the sample because of that. If you want clean looping samples, I think it's best if you familiarize yourself with how the APU DPCM channel actually works: http://wiki.nesdev.com/w/index.php/APU_DMC

It might be easier to construct the samples manually in a hex editor (or by writing a custom tool) rather than use the WAV import for it. That way you have full control over what APU is doing.

...

EDIT: For example, here's a saw(ish) DPCM wave that loops perfectly at amplitude 32:
Code:
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000  73 73 73 77 73 73 73 77 73 73 73 77 73 00 00 00  ssswssswsssws...
00000010  00                                               .

The 73, 77 section ramps the waveform down, and the 00 section ramps it back up. Of course only a limited range of frequencies can be covered by a single sample, so you'd have to have variations for different frequencies, while keeping the sample length restriction in mind at the same time.

EDIT2: I guess I should've also mentioned this technique developed by blargg that plays saw, pulse and triangle waves in the DPCM channel by playing a 1-byte sample at varying frequencies: http://www.slack.net/~ant/misc/nes-saw/ It requires custom code and IRQs though, so you can't directly use it in FamiTracker.

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


Top
 Profile  
 
PostPosted: Tue Aug 25, 2015 9:09 am 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 1835
Location: DIGDUG
I think a good strategy for DPCM samples is - first in Audacity trim all silence from before and after the sample. Then cut it to about 0.1-0.2 seconds. Then have Famitracker produce a sample that is LARGER than you want. Then save it. Open the sample in a hex editor, and trim it to exactly 16*n + 1 bytes long (where n = 1-255). Then reimport to Famitracker.

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Last edited by dougeff on Tue Aug 25, 2015 9:28 am, edited 1 time in total.

Top
 Profile  
 
PostPosted: Tue Aug 25, 2015 9:21 am 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 1835
Location: DIGDUG
Well, Here's a low C saw wave, done exactly how I described. I didn't have to edit it in a hex editor, but I have had to do that with other samples.


Attachments:
DPCM.zip [299 Bytes]
Downloaded 70 times

_________________
nesdoug.com -- blog/tutorial on programming for the NES
Top
 Profile  
 
PostPosted: Tue Aug 25, 2015 9:39 am 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 1835
Location: DIGDUG
Also, you won't be able to play looped Bass DPCM samples and Drum DPCM samples at the same time. You might want to consider Noise channel, or a combination of Noise and Sq/Tr, to simulate a drum sound.

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Top
 Profile  
 
PostPosted: Tue Aug 25, 2015 12:44 pm 
Offline
Formerly AlienX
User avatar

Joined: Fri Apr 18, 2014 7:41 am
Posts: 133
Location: Bulgaria
Thanks! That explained a lot, though I still have a question. When I asked about the selection, I didn't ask about file size, but time. So, how long would 1 byte from a sample play at rate 15? According to the wiki, 8 bits, played at rate 15 are equal to 4 scanline lengths. What does it mean by that? 4 scanlines(in which case, I'd have to find out the time it takes for the TV to draw a scanline), 4 pixels, what exactly?

Also, creating the samples in a hex editor is a pretty cool idea, but figuring out how to make a sample play an exact frequency is a pain in the ass and it also wouldn't work for some other samples I want to use. So, what I need to do right now is edit the original wave file, so that the lenght and playback rate match the ones, that can be used by the DPCM(for instance, have the file size match the formula and have the playback rate roughly around 33144.94 Hz). And for that I would need the time it takes to play a given portion of the sample. If those things are impossible, then I need to know what kind of algorithm does Famitracker use to compress the files, so that I can make the proper adjustments.

dougeff wrote:
I think a good strategy for DPCM samples is - first in Audacity trim all silence from before and after the sample. Then cut it to about 0.1-0.2 seconds. Then have Famitracker produce a sample that is LARGER than you want. Then save it. Open the sample in a hex editor, and trim it to exactly 16*n + 1 bytes long (where n = 1-255). Then reimport to Famitracker.

This is a pretty interesting idea, but the example you've made doesn't really work. It still has that problem. It's not as noticeable, but it's there. So, sorry, but it doesn't do it for me. :(

dougeff wrote:
Also, you won't be able to play looped Bass DPCM samples and Drum DPCM samples at the same time.

I know. I never said I'll have them play at the same time, though I have an interesting idea, that could simulate that. Once this problem's taken care of and I finish the track, I will post it, so you can see for yourself.

_________________
Greetings! I'm That Bio Mechanical Dude and I like creating various stuff like movies, games and of course chiptunes!
You can check out my YouTube Channel.
You can also follow me on Twitter.


Top
 Profile  
 
PostPosted: Tue Aug 25, 2015 12:57 pm 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2981
Location: Tampere, Finland
AlienX wrote:
Thanks! That explained a lot, though I still have a question. When I asked about the selection, I didn't ask about file size, but time. So, how long would 1 byte from a sample play at rate 15? According to the wiki, 8 bits, played at rate 15 are equal to 4 scanline lengths. What does it mean by that? 4 scanlines(in which case, I'd have to find out the time it takes for the TV to draw a scanline), 4 pixels, what exactly?

The scanline lengths aren't really useful for you. They're just there for people who might want to use the DPCM IRQ as a makeshift scanline IRQ.

If you're playing at rate 15, the frequency of playback (of 1-bit samples) is 1789773/54 Hz ~= 33143.94 Hz (check the table in wiki). Every byte contains 8 1-bit samples, so divide by 8 to get the frequency of how often sample bytes are fetched.

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


Top
 Profile  
 
PostPosted: Tue Aug 25, 2015 1:05 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6458
Location: UK (temporarily)
AlienX wrote:
So, how long would 1 byte from a sample play at rate 15?
The sample rates are stated on the DMC page in two different ways:
1- The "Rate Index" in the functional description, which gives the period (in CPU clocks) from bit to bit; multiply these numbers by 8 to get the number of CPU clocks to emit a whole byte.
2- The "Pitch table", which is the raw sample rates for each. (It's the same information, just 1789773 Hz divided by the above table). Divide these numbers by 8 to get the bytes/second.

To directly answer the question, the highest sample rate consumes bytes at ≈4143 bytes/second. (546875 ÷ 132 by definition)

Quote:
how to make a sample play an exact frequency is a pain in the ass and it also wouldn't work for some other samples I want to use.
Unfortunately, you're really constrained by the DMC hardware for "chip" looping samples. You basically can only get pitches that are the existing pre-provided sample rates divided by some integer.

I made a simple perl script some years ago that made triangle waves (included dmc files) for all periods in this manner, for divisors of 2 up through 127, and a reference table (included html file) of which triangle at which rate produces which pitch:


Attachments:
all-chip-dmc-triangle-waves.7z [5.04 KiB]
Downloaded 74 times
Top
 Profile  
 
PostPosted: Tue Aug 25, 2015 2:11 pm 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2981
Location: Tampere, Finland
lidnariq wrote:
I made a simple perl script some years ago that made triangle waves (included dmc files) for all periods in this manner, for divisors of 2 up through 127, and a reference table (included html file) of which triangle at which rate produces which pitch:

Cool, I was just about to do the same thing. :)

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


Top
 Profile  
 
PostPosted: Tue Aug 25, 2015 4:06 pm 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 1835
Location: DIGDUG
My sample sounds ok to me, except for a very small higher pitch click at the end of each loop.

Here's the output wav file.


Attachments:
saw1.gif
saw1.gif [ 8.7 KiB | Viewed 1788 times ]

_________________
nesdoug.com -- blog/tutorial on programming for the NES
Top
 Profile  
 
PostPosted: Tue Aug 25, 2015 8:57 pm 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 1835
Location: DIGDUG
I looked at your sample...

I think lower and longer and louder original samples sound better looped. The sample you have is too short and too quiet. Quiet, you get alot of artifact noise from the DMC sampling process. Short, you get more artifacts and misaligned peaks in the looping process, and you get a loop buzz (I don't know the technical term for this, but if you loop ANY sample short enough you get weird high pitch buzz, the shorter the loop the higher pitch the buzz).

Lower notes work better, because it's easier to match the peaks up in a loop without clipping (repeated clicks).

NES technology was just not designed to produce great looped samples. I was able to produce a less stuttered / noisy sample from your wav with a lot of modification (doubling it's length, boosting its volume, editing in hex editor), but it's still pretty noisy. Sounds a bit like a buzzing bee.

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Top
 Profile  
 
PostPosted: Tue Aug 25, 2015 9:30 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5842
Location: Canada
You can make a very limited scale with just a 17 byte looping sample, but unfortunately it is a bit detuned compared to the A440 scale usually used by programs like Famitracker.

Example: http://forums.nesdev.com/viewtopic.php?p=92494#p92494

The Immortal did this in a few tracks, it mostly just limited itself to a few droney bass notes that didn't sound too badly detuned.

If you want other pitches you need to use longer samples. To cover the pop/blip at the loop point, you can crossfade the waveform with its original phase just before the loop; this creates a phased/layered sound variation just before the loop, but it could be a lot less objectional than the pop/blip.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ] 

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