Famitracker: DPCM Loop Problem
Moderator: Moderators
- BioMechanical Dude
- Formerly AlienX
- Posts: 137
- Joined: Fri Apr 18, 2014 7:41 am
- Location: Bulgaria
Famitracker: DPCM Loop Problem
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:
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.
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:
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 605 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.
You can check out my YouTube Channel.
You can also follow me on Twitter.
Re: Famitracker: DPCM Loop Problem
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:
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.
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: Select all
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 .
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: fo.aspekt.fi
Re: Famitracker: DPCM Loop Problem
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.
Last edited by dougeff on Tue Aug 25, 2015 9:28 am, edited 1 time in total.
nesdoug.com -- blog/tutorial on programming for the NES
Re: Famitracker: DPCM Loop Problem
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 625 times
nesdoug.com -- blog/tutorial on programming for the NES
Re: Famitracker: DPCM Loop Problem
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
- BioMechanical Dude
- Formerly AlienX
- Posts: 137
- Joined: Fri Apr 18, 2014 7:41 am
- Location: Bulgaria
Re: Famitracker: DPCM Loop Problem
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.
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.
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: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.
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.dougeff wrote:Also, you won't be able to play looped Bass DPCM samples and Drum DPCM samples at the same time.
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.
You can check out my YouTube Channel.
You can also follow me on Twitter.
Re: Famitracker: DPCM Loop Problem
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.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?
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: fo.aspekt.fi
Re: Famitracker: DPCM Loop Problem
The sample rates are stated on the DMC page in two different ways:AlienX wrote:So, how long would 1 byte from a sample play at rate 15?
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)
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.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.
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 636 times
Re: Famitracker: DPCM Loop Problem
Cool, I was just about to do the same thing.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:
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
Re: Famitracker: DPCM Loop Problem
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.
Here's the output wav file.
- Attachments
-
- saw1.gif (8.7 KiB) Viewed 17414 times
nesdoug.com -- blog/tutorial on programming for the NES
Re: Famitracker: DPCM Loop Problem
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.
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
- rainwarrior
- Posts: 8731
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: Famitracker: DPCM Loop Problem
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: 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.
Example: 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.
- rainwarrior
- Posts: 8731
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: Famitracker: DPCM Loop Problem
Here's those samples stuck into a Famitracker file, in case someone wants to play with it. I had to split it into 2 instruments (4 octaves each) because there's a limit on sample entries per instrument. There's a lot of redundant notes, but I believe it always favours the one with the highest samplerate.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:
Here's also the very hastily written python program that parses the HTML file into entries for Famitracker's text import, in case someone wants to regenerate it in a different manner.
Code: Select all
notes = { "C-":0, "C#":1, "D-":2, "D#":3, "E-":4, "F-":5, "F#":6, "G-":7, "G#":8, "A-":9, "A#":10, "B-":11 }
sample = 0
lines = open("makeall.html","rt").readlines()
for line in lines[1:]:
pitches = 0
p = 0
p = line.find("<td",p+1)
p = line.find("<td",p+1)
p = line.find("<td",p+1)
p = line.find("<td",p+1)
for n in range(16):
if line[p+3] == ">":
note_name = line[p+4:p+6]
octave = int(line[p+6])-1
inst = 0
if octave >= 4:
inst = 1
note_number = notes[note_name]
print("KEYDPCM %d %d %2d %2d %2d 1 0 -1" %
(inst,octave,note_number,sample,n))
pitches += 1
p = line.find("<td",p+1)
if pitches > 0:
sample += 1
- Attachments
-
- lidnariq_triangles_split.ftm
- (19.78 KiB) Downloaded 583 times
Re: Famitracker: DPCM Loop Problem
That's cool. I was thinking about this exact thing recently.
My issues with it
-there are quite a lot of samples (53), some seem to be unused.
-some of the samples are large (1000+ bytes), and maybe not even used.
But sounds good. Thanks.
My issues with it
-there are quite a lot of samples (53), some seem to be unused.
-some of the samples are large (1000+ bytes), and maybe not even used.
But sounds good. Thanks.
nesdoug.com -- blog/tutorial on programming for the NES
- rainwarrior
- Posts: 8731
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: Famitracker: DPCM Loop Problem
Well, lidnariq's goal was to provide every possible usable sample that evenly divides the available sample lengths.
My goal was to collate as many of those as possible into a Famitracker toy you could play with as a more tactile demonstration of what it can do.
Eliminating notes and redundancies to find a practical smaller set is yet another goal, which would require someone to first spend some time figuring out what they actually need for their specific musical case, and even more time figuring out how to build the Famitracker instrument definitions that implement this smaller set.
My goal was to collate as many of those as possible into a Famitracker toy you could play with as a more tactile demonstration of what it can do.
Eliminating notes and redundancies to find a practical smaller set is yet another goal, which would require someone to first spend some time figuring out what they actually need for their specific musical case, and even more time figuring out how to build the Famitracker instrument definitions that implement this smaller set.