News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_redbox

SID Voices

Started by redbox, 14:51, 21 November 13

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

redbox

I've been working with SID voices and targeting the Plus for now (to use the DMA) but intend on also writing a version for the normal CPC and CTC-AY.

As a base I've been working with YM6 Atari ST imports just to get it working in principal.  However, although it works it doesn't sound as clear or good as it should.

This what I've been doing:
- Extracting the SID information from the YM6 registers (channel SID voice is on, VMAX and TC/TP timers) 
- Dividing the required YM frequencies by 2 to convert to from 2mhz YM to 1mhz AY (reg 0-5 in low byte, high byte multiples and reg 11 & 12 waveform periods)
- Using the ST timer to work out at which frequency the SID voice works at (i.e. (2457600/TP)/TC gives frequency) and divide this by 2 (for example, it becomes 400hz).
- Calculating the multiple of this frequency within a 15626hz CPC frame (e.g. 15625/400 = 39 lines a frame)
- Toggle the volume between VMAX and 0 every 8 lines using a DMA list

Is this correct or am I doing something wrong?  Do you need to check the frequency the note is played at and use this too?

I know it's possible from Overflow's Backtro and  F-Key's Which is Witch but am not sure what conversion process they used.

redbox

Just an update for anyone who's interested...

PulkoMandy helped on the Push'n'Pop forum and said that it was an accuracy issue due to using the 15625hz resolution on the CPC compared to the ST timers.

This has pointed me in the right direction and I'm getting nearer to it working now.

redbox

#2
Have got my player working and here is a MP3 recording to listen to - the first loop is the normal AY and the loop after that is with SID voice enabled so you can compare the difference.  Let me know what you think.

Thanks to PulkoMandy and OffseT for helping me increase the accuracy and BSC for inspiring me to work on it and general conversations about SID voices.

Next I'll work on the normal CPC version and CTC-AY version :)

(file removed)

Gryzor

I like the extra depth but there's some gargling to it?

redbox

Quote from: Gryzor on 19:04, 28 November 13
I like the extra depth but there's some gargling to it?

Well the resolution isn't perfect but what do you mean by "gargling" and where did you notice it?

Might be a WinApe issue too as I recorded it using that rather than my real Plus.

BSC

#5
Quote from: redbox on 20:50, 28 November 13
Well the resolution isn't perfect but what do you mean by "gargling" and where did you notice it?

Might be a WinApe issue too as I recorded it using that rather than my real Plus.


I also had a listen. Not bad, but I also hear the gargling Gryzor mentioned. I think it's due to the fact that the resolution is not very good, as you mentioned and also because there obviously is some sweeping. I mentioned that somewhere else when we talked: When doing SID voices (at least the Atari ST way), your volume register modulation has to be in line with the frequency of the tone at play, but not exactly, because then you could theoretically completely mute the AY voice if your volume modulation was in phase with the AY voice. Therefore, your modulation frequency has to be mildly detuned so that you achieve a sweeping effect, periodically cancelling out a small to big part of the square wave. When the 2 frequencies are too far away, the sweeping will become too fast and when it's very fast it will reach the audible range (approx > 20Hz I think) which results in a "3rd" sound at the sweeping frequency..
** My website ** Some music

My hardware: ** Schneider CPC 464 with colour screen, 64k extension, 3" and 5,25 drives and more ** Amstrad CPC 6128 with M4 board, GreaseWeazle.

redbox

Quote from: BSC on 15:50, 29 November 13
When doing SID voices (at least the Atari ST way), your volume register modulation has to be in line with the frequency of the tone at play, but not exactly, because then you could theoretically completely mute the AY voice if your volume modulation was in phase with the AY voice. Therefore, your modulation frequency has to be mildly detuned so that you achieve a sweeping effect, periodically cancelling out a small to big part of the square wave.

Yes, this is exactly what I encountered.  Problem is, the SID frequency difference is so slight that when it gets rounded down to the 15625hz in 64us multiples it gets 'lost' a lot of the time.

However, what you're describing is what I meant by "Do you need to check the frequency the note is played at and use this too?" in my original post.  Yes, I've found this is what a standard SID voice does - which means you don't actually need to read the ST timers, you can do it yourself by slightly detuning (I have tested this and it works).  Infact, using the DMA in itself slightly detunes because of it's resolution, so when using the DMA method you can hear it by simply matching the frequency of the note played.

This has lead me to think how do you achieve a better result with your player when you're using 13.8khz - is it because you can achieve a higher resolution by not being limited to a line boundary (i.e. 64us with the DMA)?  For example, 1 line could be 20 x NOP, LD PPI REG, then next 30 x NOP, LD PPI REG etc?  And if so, how long does your LD PPI REG routine take?

TotO

Fixed point math don't fix anything?
"You make one mistake in your life and the internet will never let you live it down" (Keith Goodyer)

redbox

Quote from: TotO on 20:07, 29 November 13
Fixed point math don't fix anything?

Yes, that was the fixed point version  ;)

I think maybe my choice of music wasn't the best - I just chose a random ST YM6 file with SID voices.  Some converted ST music definitely works better than others when "downgrading" to the 1mhz AY and DMA resolution.

arnoldemu

Forgive me - I am not following this thread 100% and what I am talking about already happens (with BSCs player for example).

Instead of converting SID voices from other systems what if we accepted that ours would be different? Now we've done that we are free to stop worrying about the problems of getting it to sound as it does on the ST.

We are now free to use a fixed update rate (e.g. every line), and change any register we want on this special "voice".

So to make SID-Like, we follow a sequence of volumes as BSC does (?) to make our wave. We could easily change another register (13, or 7, or a tone register) to achieve different sounds?

So now we have 2 traditional voices, and one special "voice" which we manipulate any other PSG register we want.

This would work fine with DMA on Plus, and we could make it easier on CPC.

Is there a problem related to this? Would there be bad aliasing with the tone, or would it just sound poor?



Gryzor

Re: gargling. I don't think it's the mp3 encoding - I've heard enough mp3 files to be able to understand how they were encoded and what's missing. In this case I *think* the gargling is inherent to the sound. Listen to the lower frequencies.


Of course it could be I'm wrong (I think it wouldn't be the first time, though I don't remember :D ). Maybe a better mp3?

redbox

Quote from: Gryzor on 18:29, 30 November 13
Maybe a better mp3?

I listened to it again on headphones using WinApe and it does sound better than the MP3.  Think it's a bit of both - the SID player isn't perfect but I don't think the MP3 encoding is helping (especially on the lower frequencies, as you say).  I'll try a WAV directly from my Plus when I get back to work :)

Quote from: arnoldemu on 15:34, 30 November 13
We are now free to use a fixed update rate (e.g. every line), and change any register we want on this special "voice".
So to make SID-Like, we follow a sequence of volumes as BSC does (?) to make our wave. We could easily change another register (13, or 7, or a tone register) to achieve different sounds?

I agree with your sentiment entirely and it's great that BSC is taking this approach.  However, I think there's definite merit in examining and emulating the ST SID voices because there's no point in completely re-inventing the wheel - they achieved some amazing results with the YM.

Quote from: arnoldemu on 15:34, 30 November 13
This would work fine with DMA on Plus, and we could make it easier on CPC.
Is there a problem related to this? Would there be bad aliasing with the tone, or would it just sound poor?

As far as I can see though, this is just akin to playing a sample.  How does it interact with the note being played (i.e. in regs 0/1, 2/3 or 4/5)...?  And you still have the resolution problem.  Any note that doesn't factor into the 15625hz/312 line boundary is bound to have distortion. 

What I can't get my head around is how BSC has overcome this (he does say he interpolates the frequency into his sample, so maybe this is the key) but it appears possible from the Soundcloud examples he linked to.  The only way I can see is either you have a variable line length over the whole ~20000us frame.




BSC

Quote from: redbox on 20:06, 29 November 13
Yes, this is exactly what I encountered.  Problem is, the SID frequency difference is so slight that when it gets rounded down to the 15625hz in 64us multiples it gets 'lost' a lot of the time.

However, what you're describing is what I meant by "Do you need to check the frequency the note is played at and use this too?" in my original post.  Yes, I've found this is what a standard SID voice does - which means you don't actually need to read the ST timers, you can do it yourself by slightly detuning (I have tested this and it works).  Infact, using the DMA in itself slightly detunes because of it's resolution, so when using the DMA method you can hear it by simply matching the frequency of the note played.

This has lead me to think how do you achieve a better result with your player when you're using 13.8khz - is it because you can achieve a higher resolution by not being limited to a line boundary (i.e. 64us with the DMA)?  For example, 1 line could be 20 x NOP, LD PPI REG, then next 30 x NOP, LD PPI REG etc?  And if so, how long does your LD PPI REG routine take?


Actually my player is also limited to a "line" boundary that is even worse. It's that 72us timing I mentioned. But it seems that my approach to interpolating the sample values is working quite good. I have uploaded another demo on my thread btw that you might like to try. It's playing the sounds as in one of the demos that I uploaded on soundcloud.
** My website ** Some music

My hardware: ** Schneider CPC 464 with colour screen, 64k extension, 3" and 5,25 drives and more ** Amstrad CPC 6128 with M4 board, GreaseWeazle.

BSC

Quote from: arnoldemu on 15:34, 30 November 13
Forgive me - I am not following this thread 100% and what I am talking about already happens (with BSCs player for example).
Instead of converting SID voices from other systems what if we accepted that ours would be different? Now we've done that we are free to stop worrying about the problems of getting it to sound as it does on the ST.
We are now free to use a fixed update rate (e.g. every line), and change any register we want on this special "voice".
So to make SID-Like, we follow a sequence of volumes as BSC does (?) to make our wave. We could easily change another register (13, or 7, or a tone register) to achieve different sounds?


Well put! And I fully agree (of course :D). You are right, my waveplayer works by applying a sequence of volume changes, but you can practically also alter any other AY register (the target
register is a configurable value of each instrument), so it's also possible to modulate registers 7 (even though I don't see much use here) or 13 or even the tone registers. There's a lot of
interesting possibilities using 13 or the tone registers. Working on register 13 actually yields an effect called sync buzzer (there might be other names) that I have not yet tried (or heard),
but the idea sounds very interesting. Working on the tone registers would even give you some very basic FM synthesis possibilities! I have yet to play around with that.



Quote from: arnoldemu on 15:34, 30 November 13
So now we have 2 traditional voices, and one special "voice" which we manipulate any other PSG register we want.
This would work fine with DMA on Plus, and we could make it easier on CPC.
Is there a problem related to this? Would there be bad aliasing with the tone, or would it just sound poor?


Actually, with my approach, you even have all 3 traditional voices PLUS the special one. The latter could either replace one of the AY voices (as in the demos I provided on soundcloud) or modulate any of the AY voices
(due to the fact the the target AY register is configurable per instrument) which does yield a lot of very interesting sounds. I think I have to dig out a demo where I did that and upload that one as well.. My plan (hope)
is still to finalize the player/tracker where all of this is possible. But so far, no one wanted to join the team :(
** My website ** Some music

My hardware: ** Schneider CPC 464 with colour screen, 64k extension, 3" and 5,25 drives and more ** Amstrad CPC 6128 with M4 board, GreaseWeazle.

BSC

Quote from: redbox on 18:54, 30 November 13
I agree with your sentiment entirely and it's great that BSC is taking this approach.  However, I think there's definite merit in examining and emulating the ST SID voices because there's no point in completely re-inventing the wheel - they achieved some amazing results with the YM.

As far as I can see though, this is just akin to playing a sample.  How does it interact with the note being played (i.e. in regs 0/1, 2/3 or 4/5)...?  And you still have the resolution problem.  Any note that doesn't factor into the 15625hz/312 line boundary is bound to have distortion. 

What I can't get my head around is how BSC has overcome this (he does say he interpolates the frequency into his sample, so maybe this is the key) but it appears possible from the Soundcloud examples he linked to.  The only way I can see is either you have a variable line length over the whole ~20000us frame.


I don't think there's any need to re-invent anything. Its already done! And the CPC does not have a 2mhz clocked YM but a 1mhz clocked AY to start with. I could not have been bothered to try converting existing Atari approaches or even players, but that's just me and I appreciate that you are still going that way! Even though I'd prefer if you joined forces with me instead ;)


About the soundcloud examples: I have just uploaded another dsk file to my thread where you can reproduce the demo you mentioned on your favourite emulated CPC :)
And I thought that I have explained how it works already, but it seems I haven't yet managed to make it clear enough..? All the magic - I think - is in the interpolation and
the fact that I have a stable sample/replay rate all the time. Even when doing instrument/pattern/song logic. That's because I interweaved that logic with sample replay
(which was cumbersome and has to be done programmatically in the future) so that there's really always a sample rate of 13.8khz. It's far from perfect, though, as you
can hear on the higher notes especially. But, as I also already said: I think it's about the best you can do it on a CPC and even if I were playing at 15khz there would be
aliasing effects. After all it's just a little CPC trying to sound like something else...
** My website ** Some music

My hardware: ** Schneider CPC 464 with colour screen, 64k extension, 3" and 5,25 drives and more ** Amstrad CPC 6128 with M4 board, GreaseWeazle.

redbox

Quote from: BSC on 23:08, 30 November 13
Even though I'd prefer if you joined forces with me instead ;)

I'd be more than willing to help, just awaiting the source  :)

Quote from: BSC on 23:08, 30 November 13
And I thought that I have explained how it works already, but it seems I haven't yet managed to make it clear enough..? All the magic - I think - is in the interpolation and the fact that I have a stable sample/replay rate all the time.

I understand the need and how to keep it "stable".  What I still don't get is how your interpolate the original frequency generated by the AY with your "samples", and specifically how these samples can work for all (well most without distortion) frequencies generated.  Can you explain this process please?

arnoldemu

Quote from: redbox on 18:54, 30 November 13
As far as I can see though, this is just akin to playing a sample.  How does it interact with the note being played (i.e. in regs 0/1, 2/3 or 4/5)...?  And you still have the resolution problem.  Any note that doesn't factor into the 15625hz/312 line boundary is bound to have distortion. 
yes it is like playing a sample. And, just as the current SID-Voices do, you use the volume to modulate the tone output.

I can see that simulating the ST approach is troublesome for CPC. And the ST approach was to simulate the c64.

Ont the amiga they have "chip-tunes" which are reproducing the c64 like sound on the amiga.

I was just thinking, embrace our limitations, and let the musician work within them to create interesting effects, and then we can also fit demos/code around it more easily knowing the constant AY updates that are needed.

I am interested in SID-Voice and have been for a long time. This conversation comes at a time when I can't participate fully because I have work and other cpc commitments.

redbox

Quote from: arnoldemu on 10:02, 02 December 13
yes it is like playing a sample. And, just as the current SID-Voices do, you use the volume to modulate the tone output.

I've been thinking about this and as far as I can see this is what you could do:

1) have a volume based "sample" consisting of 1 waveform (sinus wave for example) at a set frequency
2) take the output frequency of the AY and then compare this to the "sample" frequency
3) calculate the ratio of the frequencies and step and cycle through the "sample" at a set rate

So if you had a "sample" frequency at 200hz and the AY produced a tone of 200hz then you'd just step through the "sample" at a rate of 1:1.  If the AY produced a tone of 400hz, you'd step through the sample at a rate of 2:1.  This then in turn would turn our square AY wave into a sine wave.

Is this right?  And is this in essence what BSC is doing with his player?  And what frequency do you set the "sample" at?

BSC

Quote from: redbox on 11:19, 02 December 13
I've been thinking about this and as far as I can see this is what you could do:

1) have a volume based "sample" consisting of 1 waveform (sinus wave for example) at a set frequency
2) take the output frequency of the AY and then compare this to the "sample" frequency
3) calculate the ratio of the frequencies and step and cycle through the "sample" at a set rate

So if you had a "sample" frequency at 200hz and the AY produced a tone of 200hz then you'd just step through the "sample" at a rate of 1:1.  If the AY produced a tone of 400hz, you'd step through the sample at a rate of 2:1.  This then in turn would turn our square AY wave into a sine wave.

Is this right?  And is this in essence what BSC is doing with his player?  And what frequency do you set the "sample" at?


I think there is one big misunderstanding at least concerning my engine. None of the effects you could hear in the demos (and basically the way I want to achieve any "SID effect" at all) was achieved by modulating an existing AY tone. Instead, the according AY voice was muted, so there's no need to synchronize the sample play frequency with anything. For me, this would be just an option to achieve even more modulation possibilities, like modulating the AY tone with a sine wave. So in essence my player is only doing step 1 and 3 from above, and the frequency at which a given sample is played is completely dependent of the tone you want to play. I have a pre-calculated table of offsets (comparable to the periods table for classic AY music) which are based on the replay rate (72us) and the sample length (256 bytes) and there's a value for each semi-tone on 8 octaves. You could compare the engine with the AHX player on the Amiga, where you really only play micro-samples to which you apply all the possible modulations (volume, tone, semi-tone for arpeggios etc., wave-form changes) by somehow modifying the micro-samples (in real time). In my player, the SID-effect itself is achieved by cycling through a list of square waves with different pulse-width and tone modulation, for example, is done by applying a signed offset to the current tone offset based on the tone that is played. So, if you wanted to modulate one AY channel by the wave table player, you actually had to write two voices, depending on what you want to achieve.
** My website ** Some music

My hardware: ** Schneider CPC 464 with colour screen, 64k extension, 3" and 5,25 drives and more ** Amstrad CPC 6128 with M4 board, GreaseWeazle.

BSC

#19
Quote from: redbox on 23:17, 30 November 13
I'd be more than willing to help, just awaiting the source  :)
Good to know! :) I'll to that as soon as possible. Bear in mind, though, that I found that the current source code is not really in a state where it makes a lot of sense to publish it (without triggering a huge cascade of questions, I guess), so I have to clean up and refactor before I can put it on git-hub..

Quote from: redbox on 23:17, 30 November 13
I understand the need and how to keep it "stable".  What I still don't get is how your interpolate the original frequency generated by the AY with your "samples", and specifically how these samples can work for all (well most without distortion) frequencies generated.  Can you explain this process please?

Please see my other response concerning synchronizing the wave player with AY tones..

For playing samples, the player picks a sample value from the wave table and sends it to the AY every 72us and acts on the volume register that is configured by the current instrument. Walking the wave table (which is page aligned, e.g. starts at $8000 and always 256 bytes for each wave form) is done by adding a 16 bit offset which reflects the current tone (low offsets yield low notes etc.) to a 16 bit index value. Of that index, only the high byte is used to pick any of the 256 values from the wave table. This is my version of using 8 bit fixed point math for interpolation. An example: Suppose I have a offset value of 800. Index is initially 0, so this is how it goes:

(index value, hex offset, hex low byte to index wave table): 0,0,0; 800,$320,$3; 1600,$640,$6; 2400,$960,$9; 3200;$c80;$c .. you get the point. If offset was 1600, the index values would be 0,$6,$c,$12 and for 400 it would be 0,$1,$3,$4 and so on.. I think the good audio results are mainly due to the fact that the comparably simple wave forms are stretched out over 256 bytes, so that the relative error leading to aliasing effects is very low on the lower notes..


; preparation, i.e. b is set every time the instrument changes, de is set every time the pitch changes, hl is set when the player starts
ld hl,0; initial index
ld de,800; offset from the tone-table
ld b,$80; our sample is at $8000 to $80ff


; done every 72us
add hl,de; add offset
ld c,h; adjust wave pointer
ld a,(bc); fetch sample value



and the value in a is then sent to the volume register.
** My website ** Some music

My hardware: ** Schneider CPC 464 with colour screen, 64k extension, 3" and 5,25 drives and more ** Amstrad CPC 6128 with M4 board, GreaseWeazle.

redbox

What a great idea.  :)

Thanks for the explanation.  I'm going to work on it now!!!

BSC

Let me know when you have got something new to listen to, I am really curious :)



** My website ** Some music

My hardware: ** Schneider CPC 464 with colour screen, 64k extension, 3" and 5,25 drives and more ** Amstrad CPC 6128 with M4 board, GreaseWeazle.

redbox

Quote from: BSC on 10:05, 11 December 13
Let me know when you have got something new to listen to, I am really curious :)

Yay, I've done it using a wave table  :)

Here is the normal AY output waveform:



Here is the same waveform generated using a wave table (via DMA at the moment):



And here is generated waveform as a "SID voice" (check out the unfixed square wave ratio):



I used WinAPE to monitor the output so it isn't exactly perfect but it shows it working ;)

redbox

Well I've taken a different approach and given up on trying to emulate the ST  ;)   However, I learnt a lot from the ST way of doing things and incorporated this into my new player.

I now modulate the existing AY tone with a waveform built from a wave table.  The reason I wanted to do this is because I want to eventually have the ability to add SID voices to Arkos Tracker compositions.

The example MP3 attached is the Commando tune.  It's normal AY first followed by the SID voice version.

The tune is still using square waveforms but the duty cycle is altered by using a delay.  In this example the delay is fixed and so is the volume, but in future versions these will both be variable.  I should also be able to implement sinus waveforms and different SID gates too.

Feedback on the MP3 would be appreciated.  :)

BSC

Quote from: redbox on 15:09, 16 December 13
Well I've taken a different approach and given up on trying to emulate the ST  ;)   However, I learnt a lot from the ST way of doing things and incorporated this into my new player.


That I like :)


Quote from: redbox on 15:09, 16 December 13
I now modulate the existing AY tone with a waveform built from a wave table.  The reason I wanted to do this is because I want to eventually have the ability to add SID voices to Arkos Tracker compositions.


Was this run on a Plus or CPC? It sounds really great! Could you elaborate a bit on how this is achieved technically?


Quote from: redbox on 15:09, 16 December 13
The tune is still using square waveforms but the duty cycle is altered by using a delay.  In this example the delay is fixed and so is the volume, but in future versions these will both be variable.  I should also be able to implement sinus waveforms and different SID gates too.

Feedback on the MP3 would be appreciated.  :)


Well, it sounds really great! But what is this delay thing you mentioned?


Keep going! :D

** My website ** Some music

My hardware: ** Schneider CPC 464 with colour screen, 64k extension, 3" and 5,25 drives and more ** Amstrad CPC 6128 with M4 board, GreaseWeazle.

Powered by SMFPacks Menu Editor Mod