Monday 26 March 2018

A 48Khz digital music player for the Commodore 64

Move over, Sennheiser. Make yourself scarce, Bose. Here comes the ultimate Hi-Fi solution for your living room: The Commodore 64!
Is it safe to give up your subscription to Spotify yet? Let's find out.


Preface

Unlike my previous posts, this article requires a good understanding of 6502 Assembly. If you are still wasting your time with the likes of Java, Python, or whatever they told you it is in fashion in 2018, you might want to reconsider your priorities: it's not too late to learn this magnificent programming language. You might even land a job at NASA. You will thank me later.
As readers of these pages know, I've always been obsessed with audio and video compression for humble machines. My game Planet Golf for the Commodore 64 even includes Full Motion Video running from a floppy disk. The problem with this stuff, though, is that, as much as it's interesting to see these experiments run on such a limited piece of HW, and as much as it feels like an achievement to the programmer, that doesn't change their gimmicky nature. In other words, let's be honest, no person in their right frame of mind would waste a second of their time listening to those scratchy sounds, unless deafened by unconditional love for the machine. Spoiled as we are with high quality sound coming from all kinds of devices around us, poor Commodore 64 cannot be our to-go solution for our aural pleasure.
Or can it?

Mission

To build a C64 software player that can play a whole song at 48Khz (higher frequency than CDs' 44.1Khz) using a stock Commodore 64 and a regular ROM cartridge, which is your typical 80s setup.
Now, there are all kinds of devilish pieces of hardware available for your Commodore 64 nowadays, such as 16Mb RAM Expansion Units, or even mp3 hardware players. Of course, this stuff was not around in the 80s, and it therefore does not appeal to purists. In other words, any reliance on these monstrosities would get me disqualified. You might as well run a marathon riding a motorbike.
The largest "legitimate" ROM Cartridges are those that Ocean used for their games. You can store a whopping one megabyte of data onto them. We are going to need all of it!

In Numbers

So, we are playing 8-bit samples at 48Khz from one megabyte of storage, minus few Kbytes for the actual player code. This leaves us with 48Kb to encode one second of uncompressed audio, and means that the whole cartridge can barely contain 20 seconds of audio. Which means that we must implement some form of compression, ideally at least 4:1 to get close to 1m30 sec of audio.
Commodore 64's CPU runs at roughly 1Mhz. This means that, if we want to play 48000 samples per second, we only have about 100000/48000 = 21 CPU clock cycles per sample.
Now, how does playing a sample occur? C64 can play 8-bit samples, using a trick that has been recently invented by Pex Tufvesson. The oscillators must be configured and locked in a certain way, and after that, writing to the volume register generates a shift in the voltage, which in turn makes the sample audible. Unfortunately, unlike the 4-bit playing technique, this shift is not linear with the sample value. Therefore, one needs to read an 8-bit entry from memory, use that entry to fetch an amplitude value from a LUT, and finally write this amplitude value into the SID volume register, $d418. Assuming that our first sample sits at $8400, and that our 256 entries lookup table sits at $1000, this is what we need to do to play the first sample.

 ldx $8400  
 lda $1000,x  
 sta $d418  


These three instructions take 4 cycles each, so 12 clock cycles out of the 21 we can afford are gone just to play one sample, and we haven't even added the loop logic and the compression!
This means that whatever form of compression we come up with, it must be extremely efficient and snappy. Possibly, again, a simple look up from a table.
Vector Quantization springs to mind: we need a set of 4-byte codebooks so that, splitting the original waveform in blocks of 4 adjacent samples, each of these blocks can be represented by an index in the codebook table, and ideally the number of codebooks should be 256, so that we can use a single byte as an index. This yields the 4:1 compression ratio that we are seeking, but to use only 256 codebooks for a whole song and maintain a good quality is wishful thinking. That is why most vector quantization based compression codecs need a dynamic codebook set. As the playing progresses, least recently used codebooks are discarded and replaced with fresher ones encoded in the actual bitstream. With so few clock cycles available, though, we can't even think of implementing such a complex scheme, so our approach will be to periodically replace all of the codebooks.
Although not optimal from the point of view of the quality, this solution actually plays very well along the limitations of the cartridge, which is operated by means of bank switching. One could think of switching bank and switching codebooks at the same time.
Each bank consists of 16Kbytes. If we use 256 4-byte codebooks for each of these banks, we "waste" 1Kb for the codebooks set and are left with 15 Kb to store 15*1024 entries which will translate to 15*1024*4 samples. The added footprint of the codebooks reduces the compression ratio from 4:1 to 3.75:1, but we can live with that.
We'll see later what the encoder looks like, although there'll be no huge surprises.

The play routine

The cartridge layout consists of 64 banks of 16 Kbytes each. Within the commodore 64 address space, each of these banks can be mapped to $8000-$BFFF. By writing values from $00 to $3f to cart register $de00 we can switch-in one of the 64 banks. We'll place our set of codebooks for each bank at the beginning of the dataset, in an interlaced way. So the first byte of the first codebook will be at $8000, the second will be at $8100 and so on. The n-th byte of the m-th codebook will be at $8000 + n*$100 + m
So our player will look like:


 For (bank = $00; bank <= $3F; bank++)  
 {  
      bank->$de00 //select bank   
      For (i = $8400; I < $c000; i++)  
      {  
           Id = mem[i]  
           Sample0 = mem[$8000 + Id]  
           SYNC()  
           PLAY(Sample0) //store value to $d418  
           Sample1 = mem[$8100 + Id]  
           SYNC()  
           PLAY(Sample1) //store value to $d418  
           Sample2 = mem[$8200 + Id]  
           SYNC()  
           PLAY(Sample2) //store value to $d418  
           Sample3 = mem[$8300 + Id]  
           SYNC()  
           PLAY(Sample3) //store value to $d418  
      }  
 }  


The SYNC() pseudo function is the key here. The actual playing, which means writing the sample value to register $d418, must occur exactly every 21 clock cycles. In fact, it's not that important that the actual frequency of 48000Hz is precisely matched (few Hz more or less won't make that much of a difference), what really counts is that the same frequency is maintained. What would happen if we played one of those 4 samples in the loop, say, 20 cycles after the previous one? That would add an ear-piercing high-frequency phase noise distortion to the sample. This kind of jittering is not a problem at very low frequencies (we'll use that to our advantage), but at 12Khz (1 in every 4 samples) it will seriously affect the quality of the output.
Now that we know all the constraints, let's take a look at a possible first version of the player. Which plays an entire bank from the cartridge.

       
sample:        ldx $8400  
               ldy $8000,x  
               lda sidtable,y   
               sta $d418     
               nop   //wastes 2 cycles  
               nop   //wastes 2 cycles  
               nop   //wastes 2 cycles  
               bit $ea //wastes 3 cycles  
               ldy $8100,x          
               lda sidtable,y   
               sta $d418           
               nop   //wastes 2 cycles  
               nop   //wastes 2 cycles  
               nop   //wastes 2 cycles  
               bit $ea //wastes 3 cycles  
               ldy $8200,x          
               lda sidtable,y   
               sta $d418  
               nop   //wastes 2 cycles  
               nop   //wastes 2 cycles  
               nop   //wastes 2 cycles  
               bit $ea //wastes 3 cycles  
               ldy $8300,x  //4 cycles     
               sidtable,y //4 cycles  
               sta $d418    //4 cycles  
               inc sample + 1 //6 cycles  
               bne sample    //2 cycles if jump does not occur,
                             //3 otherwise  
               inc sample + 2  
               lda sample + 2  
               cmp #$c0  
               bne sample  

                                               
Now - this does what we need in terms of decoding and playing the data, but timing is completely screwed up. If you check the "distance" between two consecutive operations STA $d418, for the first three samples it takes exactly 21 cycles, but problems arise when you get to the last block. Altering the sample read address and looping back takes a variable amount of cycles. In case we are not crossing the page boundary, when the bne sample instruction actually jumps, we are very lucky, because the loop takes exactly 21 cycles until the next STA $d418. On the other hand, if the jump does not occur, the number of cycles until the next STA $d418 becomes 35!
One could say that this only happens once every 256 code entries, so once every 1024 samples, and that is not a big deal, after all. Unfortunately, at these high frequencies this means that the distortion would still be quite noticeable. We must get rid of those final 14 cycles. Since every 16Kb cart block only has 15Kb of actual code data, which is 60 pages, one could think of unrolling the external loop. Let's give it a try:

 For (i=0; i<60; i++)  
 {  
       sample:           ldx $8400 + i*$100  
                         ldy $8000,x  
                         lda sidtable,y   
                         sta $d418     
                         nop               //wastes 2 cycles  
                         nop               //wastes 2 cycles  
                         nop               //wastes 2 cycles  
                         bit $ea           //wastes 3 cycles  
                         ldy $8100,x          
                         lda sidtable,y   
                         sta $d418           
                         nop               //wastes 2 cycles  
                         nop               //wastes 2 cycles  
                         nop               //wastes 2 cycles  
                         bit $ea           //wastes 3 cycles  
                         ldy $8200,x          
                         lda sidtable,y   
                         sta $d418  
                         nop               //wastes 2 cycles  
                         nop               //wastes 2 cycles
                         nop               //wastes 2 cycles
                         bit $ea           //wastes 3 cycles  
                         ldy $8300,x       //4 cycles     
                         lda sidtable,y    //4 cycles  
                         sta $d418         //4 cycles  
                         inc sample + 1    //6 cycles  
                         bne sample        //2 cycles if jump does not occur,
                                           //3 otherwise 
 }  

That is starting to look better: each sample plays exactly after 21 cycles, like in the previous version. There are still a couple of issues, though. When the last sample is played, the bne sample instruction only takes 2 cycles, so the following sample is played after 20 cycles, not 21. One cycle less every 1024 samples is not as bad as 14 more, but still not acceptable. More than this, though, there's a serious problem with loop unrolling on the C64: When branches occur across pages, they take one cycle more! Some of these 60 play routines will certainly end up crossing page boundaries, hence screwing up the timing once again. What we can do is to align the loops at the page boundary, but this would add gaps in between the play routines. These gaps must be jumped over with a jmp instruction, which in turn adds another 3 cycles, once again screwing up the timing. In fact, if you take a look at what happens to the end of the first play routine, you'll see something like this:

                   sta $d418           //4 cycles  
                   inc sample + 1      //6 cycles  
                   bne sample          //2 cycles if jump does not occur,
                                       //3 otherwise  
                   jmp nextblock       //3 cycles  
.align 
sample:            ldx $8400 + i*$100  //4 cycles  
                   ldy $8000,x         //4 cycles  
                   lda sidtable,y      //4 cycles  
                   sta $d418           //4 cycles  

27 cycles!
It's a bit like solving a Sudoku puzzle, isn't it? And this is getting a bit boring too, so, without further ado, I present you with the final version:

 .for (var i=0; i<60; i++)                   
 {  
       l:                nop                 
       sample:           ldx $8400 + i*$100  
                         ldy $8000,x  
                         lda sidtable,y   
                         sta $d418      
                         inc sample +1        
                         bit $ea               
                         ldy $8100,x          
                         lda sidtable,y   
                         sta $d418            
                         inc $d020  
                         bit $ea               
                         ldy $8200,x         
                         lda sidtable,y   
                         sta $d418          
                         bit $ea             //3
                         nop                 //5  
                         ldy $8300,x         //9  
                         lda sidtable,y      //13  
                         ldy sample + 1      //17          
                         sta $d418           //21  
                         bne l               //2 cycles. 3 cycles if jumps 
                                             //to the first nop 
                         jmp nextblock+1     //3 
.align 64                //the whole code is less than 64 bytes
                         //so aligning to 64 should fit 4 blocks in one page,
                         //while still preventing cross-page branching
       nextblock:
                         //there'll be a nop here,
                         // but it will not be executed at the first run  
}  

If you check all the possible "paths" within this code, you'll find out that writes to $d418 always occur 21 clock cycles apart, no matter the flow. The secret was to "spread" all of the loop handling logic across the 4 sample play sections in each loop, leveraging those sync dummy operations to do something useful rather than active wait, thus saving precious cycles in the last block to accommodate the jmp to the next page play routine.
Now each of the 1024*60 samples played from a cartridge bank plays exactly 21 cycles after the previous one, and we even managed to squeeze in an inc $d020, to show some raster effect on the screen.
Now I hear you say, there must still be some code to switch banks, and that will waste precious clock cycles, adding some delay.
You are right, but we don't have to do anything about that. We are talking about an off-sync every 60000 sample, that is 1.28 seconds: a phase noise at a frequency that is lower than 1hz, which is not audible.
Job done.

Songs

1:30 might sound like a tight limitation, but there are still plenty of songs that come in at less than 90 seconds. I ended up choosing Elvis Costello's "Welcome to the Working Week", from his debut album My Aim is True, and my favourite piece of music from my favourite progressive band: Jethro Tull's "Cheap Day Return", from the seminal record Aqualung
Both Aqualung and My Aim is True are available in digitally remastered edition in 96khz 24bit lossless format:  plenty of quality to start from.


The encoder

Vector Quantization is an easy approach to achieve decent compression with minimal impact on the decoder performance. In fact, in the setup I've used, it only takes a single lookup from the codebook table to fetch a sample. In order to obtain about X:1 compression, one needs to split a given PCM vector of n samples into n/x vectors of x consecutive samples, with x=4 in our case. This would be the input to a round of clustering, typically K-means, with K=256 in our case being the number of codebooks we want to compute.
Since K is a power of 2, we can also use LBG, which, in this case, performs slightly better.
But more than the clustering algorithm, what really makes the difference here is the way we can prepare the data. Rather than using the original PCM waveform, I worked with a delta representation of the square root of each sample.
Let's say that A is our waveform with -1.0<ai<1.0 for each sample, our clustering pass runs instead on the pseudo waveform B which is defined as  

bi = sign(ai)*sqrt(|ai|) – sign(ai-1)*sqrt(|ai-1|)

The square root works as a poor man's amplification filter for high-frequency parts or for fricative sounds that typically come with low amplitude. The clustering pass would otherwise zero these finer details. The use of differential pcm, instead, brings in the idea that transitions, more than absolute values, are what we actually hear in a waveform.
Of course the set of codebooks that we obtain from this clustering pass is not representative of the original waveform A, only the clusters are. Therefore, we must recompute the centroids of the clusters using the actual vectors from A.
Higher values of K can be used, which lead to higher compression rates at the cost of quality.
K=4, as used in the demo, brings in a minimal degradation. I've experimented with higher values and K=8 is still kind of acceptable, and allows for almost 3 minutes of music to fit on a cartridge, but of course much depends on the type of content that we are encoding.
In the following picture you can see, in order, 500msec of the original, uncompressed audio, the differential on the squared signal used as input for the encoder, and the codebook-reconstructed 8-bit waveform, which is what the C64 plays


Further Development

I got a lot of "Why don't you use a 16Mb REU?" As I said, I'm not really keen on using HW that is not true to the spirit of the 80s. REUs (Ram Expansion Units) did exist in the 80s, but only came in 128, 256 and 512kb cuts. 16Mb REUs are just a modern thing and, although one could in theory put an entire record onto a 16Mb REU with this encoder, where would the fun be? One advantage that REUs have over a cartridge, though, is that, being RAM, you can actually write it. This means that the amplitude values for a specific SID chip could be hardcoded to the codebooks before we play the song, and the lookup from the sidtable would no longer be needed at playtime, freeing 4 precious clock cycles per sample, and thus paving the way to even higher sampling frequencies, if that even makes sense. How about a 64Khz compressed-audio player? Not sure the difference would be audible and that it would make much sense, but again nothing here makes sense in first place, so why not?
The second most asked question is, "Will you release the encoder"? Well, the encoder is just a bunch of Python scripts at the moment, and it's described in this very blog post, so in theory anyone can recreate it now, but I guess it would still be nice to release a user-friendly application for those who don't want to mess around with scikit-learn. If I am not distracted by even more ridiculous projects, that is what I am doing next.

Reception

The demo was well-received and got quite some attention. I shared the YouTube previews right before I uploaded the actual demo to CSDB, just because that requires a bit more time. Still, those few minutes that passed between the two actions caused a lot of people to shout "fake!", despite the fact that I had stated that the download would have been available shortly. I guess that "it sounds so good I think it's fake" counts as the most flattering of the compliments!
The demo is currently number 9 in CSDB's top C64 demos of all time, which, you could say, is a bit of an overestimation of the actual value of the production. And I totally agree.
The fact is that the demo doesn't really break any new ground: Vector Quantization has been used in few productions already (although I'm not sure about the combination with DPCM), and high-frequency digi playing has been a thing for quite some time, mostly thanks to the oustanding work of Pex Tufvesson. I guess that doing the two things together, on a proper song, rather than a second or two of speech, was a low hanging fruit that someone had to reap at some point. I was happy to do it, but the real innovators are people like Pex.

Appendix

I also developed a 3-byte codebook version of the player, so that I could use a less destructive compression for songs that do not make it past the 60-second mark. This was a bit trickier because there are fewer cycles available in the main loop to "spread" the instructions controlling the loop itself. At some point, I needed to add 1 cycle to the last playing write, which is not all that easy because no instruction takes less than 2 cycles, so you can only add 2. I ended up slowing down the read from sidtable just for that single write, which can be done using the y indirect addressing mode.
The "Mazinger Z" song, encoded with this technique, really sounds as good as the original.


.for (var i=0; i<61; i++)                   
{  
       l:                nop                 
       sample:           ldx $8300 + i*$100  
                         ldy $8000,x  
                         lda sidtable,y   
                         sta $d418      
                         inc sample +1        
                         bit $ea              
                         ldy $8100,x           
                         lda sidtable,y   
                         sta $d418
                         sty $d020           
                         ldy $8200,x          
                         lda ($fb),y         //like lda sidtable,y but a cycle more  
                         ldy sample + 1               
                         sta $d418
                         bne l                
                         jmp nextblock+1       
        .align 64  
        nextblock:  
}  


174 comments:

  1. 16MB RAM expansions for C64 (REU) was availble in the eighties.

    ReplyDelete
    Replies
    1. I'm not aware of that.
      Commodore only ever produced three models:
      1700, 1764 and 1750, that is 128kb,256kb and 512kb.
      Other companies, Such as Creative Micro Design, manufactured REU clones, that came in cuts as large as 1Mb. The RamLink, specifically, could be in theory expanded to 16Mb, but that was not available in the 80s. Furthermore, in REU mode, only a maximum of 2Mb could be addressed.

      Delete
    2. 32MB was $1000 in 1995. I seriously doubt any 16MB REUs were produced in the 80s... for a $199 computer.

      Delete
    3. The amount of RAM is unimportant. Every REU works the same, it´s just that the built-in memory is different. I, too, doubt that a 16mb REU was available in the 80s, but only because of the high price tag, not because of any technical issues. The original REU was "capped" for fastest performance, that´s why it´s not checking (and thus wrapping) at the 2mb bank. But any memory bank (up to 16mb) can be addresses "manually".

      Check out Bad Reception TV (http://csdb.dk/release/?id=160140), it´s playing videos from a 16mb REU with digitized audio

      Delete
    4. OK not technically the 80's, but the CMD RAMLink (released in 1993) could be outfitted with 16MB of memory. It could also emulate memory expansions in various sizes (via a DACC partition). The standard REU sizes were common but I believe you could make them as large as you wanted.

      I say believe because even I unfortunately can't test it out myself and I'm only now just finding out about it. I did own one back in the day that was maxed out to 16MB (bought it through a promotion RUN magazine was having... I still remember that stupid little detail to this day. :D). My naive earlier self didn't even realize it could emulate an REU and do everything else it did at the same time so I never took advantage of that feature. Like an idiot I had sold my system and the RAMLink to buy an Amiga 1200. :(

      Oh how I wish I still had that setup. :(

      Delete
    5. If 16MB RAM expansion was available in the 80s - and it very well might have - it would have been COLOSSALLY expensive, well into the thousands of dollars. In 1988, for example, 1MB of RAM cost about $500, so 16MB would be in the $8000 range.

      Delete
  2. Dreamy article. Makes my morning to read!

    ReplyDelete
  3. Pretty Amazing! I grew up on C64's and I remember an old Billy Idol Demo of Flesh for fantasy and it was just a few second looped clip and I was amazed by that. This would have blown my mind in fact knowing the limitation you are working under it still does! nice work!

    ReplyDelete
    Replies
    1. https://www.youtube.com/watch?v=R_mrtqslzZs

      Delete
  4. Very nice work and write-up. I experimented with VQ for realtime playback of compressed audio data in 2013; result works on 8088 systems (or dosbox) and is available at ftp://ftp.oldskool.org/pub/misc/temp/gb.zip if you're curious. I did not work with prioritizing deltas, nor an amplification filter, so if I revisit this in the future I'll be sure to give that a shot. Other ideas: Codebook of only deltas (ie. not recomputed from the centroid), and also streaming updates to the codebook. Both of these ideas have the downside of no longer being able to seek and playback from anywhere in the file, though; you'd be limited to starting at the beginning and playing through linearly. For most applications, this is fine.

    ReplyDelete
    Replies
    1. Neat stuff you got there, Trixter! Thanks for your comment.
      I tried differentials in the player (not just the encoder), and there is some quality gain for higher values of K. The problem is that handling the DPCM logic at playtime becomes too complex for 48Khz, at least on the C64. If you look at the code, there's hardly a single clock cycle left...

      Delete
    2. I agree, it takes more CPU time to do. My target is 16KHz, not 48KHz as yours is, so I have a little more CPU time than you to perform some additional operations per sample.

      Delete
  5. amazing work! Any place we can download the .crt file with Jethro Tull song?

    ReplyDelete
    Replies
    1. I did not upload it to CSDB because I didn't want to flood it with too much of the same stuff. I thought 1 example for the 4-byte codebooks (Elvis Costello) and one for the 3-byte codebooks (Mazinger Z) was enough. Maybe I'll upload it somewhere else.

      Delete
    2. yes please.. because for me the Mazinger Z with noisy-soundtrack is far less impressive, although loving all those robots cartoon shows... especially Nihongo!

      Delete
    3. Based on the raster patterns in youtube video, the MazingerZ seem to run at a different rate than the 2 others. The CSDB link show a screen shot of Elvis Costello & Mazinger Z version.. the zip file seem to contains only the Mazinger Z?

      Delete
    4. The screen color is changed every codebook, not every sample because there's not enough rastertime. So it's once every 4 samples in the Costello demo, and once every 3 samples for the Mazinger demo, because they are using respectively 4 and 3 byte codebooks.
      The link for the Costello demo is buried in the comments of the the first one one, you are right :-).
      Here are the downloads:
      Mazinger:
      http://csdb.dk/release/?id=162941
      Costello:
      http://csdb.dk/release/?id=162951

      Delete
  6. Could you clarify this: "Of course the set of codebooks that we obtain from this clustering pass is not representative of the original waveform A, only the clusters are. Therefore, we must recompute the centroids of the clusters using the actual vectors from A."

    Are you saying you use the delta clusters as a guide to pick codebook entries from the source data, or do you create new codebook entries by finding the starting sample for a cluster and applying the delta codebook to come up with the result?

    ReplyDelete
    Replies
    1. The clustering is done on the differential waveform B. At the end of the clustering process you have a set of clusters and the codebooks. The codebooks are computed on the differential waveform, and we just discard them. The clusters contain all the indices to the 4-byte vectors of the waveform B. Now, if we compute the mean of all the vectors in a cluster we obtain the set of centroids (codebooks) that we have just discarded. So what we do is to use those indices to access the 4-byte segments of the original waveform, A, instead of B.

      Delete
    2. Okay, that's very clear, thanks!

      Delete
  7. The Voyager space probe does not use 6502 Assembly, but was originally written in Fortran 5 then ported to Fortran 77.

    Most specifically, it is not a 6502 CPU.

    https://www.allaboutcircuits.com/news/voyager-mission-anniversary-computers-command-data-attitude-control/

    ReplyDelete
  8. This comment has been removed by a blog administrator.

    ReplyDelete
  9. This comment has been removed by a blog administrator.

    ReplyDelete
  10. Not having owned a C64 (was a proud CPC464 user back then) makes me an outsider with no right to comment here. BUT I just had to say that this is amazing and although the C64 was a very successful machine back in the good old 80s, I think that if this hack was released back then, it would have caused a big sensation. Well done.

    ReplyDelete

  11. wow... wait what.. i mean FREAKING WOW. amazing, and a great write up also. thanks muchly

    ReplyDelete
  12. This comment has been removed by the author.

    ReplyDelete
  13. Impressive work, to be sure. Thank you for sharing, and for continuing to push the limits of the humble (yet history-altering) bread bin.

    One question: why was a sampling rate of 48kHz chosen? That had far-reaching consequences, of course. That frequency is the Nyquist Frequency, only frequencies half of that value (in this case 24kHz)and lower will be captured by the sampling.

    Human hearing is typically cited as extending to 20kHz (for children), and dropping as we age.

    Perhaps capturing frequencies up to, say, 16kHz would suffice,in which case the sampling rate could be reduced to 32kHz. Surely, that would have a beneficial impact on the code.

    ReplyDelete
    Replies
    1. Well, I guess the answer is: Just because it was possible.
      Really, it's just to claim a ridiculous advantage over the CD, which samples at 44.1khz. Nowadays 96khz music is also a thing. Quite overkill, one could argue, but it's there.

      Delete
  14. This comment has been removed by the author.

    ReplyDelete
  15. Very interesting read. I'll have to read up more on vector quantization.

    I experimented with digi-sounds in 1987/88 and wrote a 4-bit sequencer which used an index table to play back individually sampled segments and recreate the original track. I had to manually break a full record into segments that repeated (cutting at the zero point), sampled each segment at an optimal rate to conserve memory, and then replayed the segments at their specific rates via NMI interrupts.

    It worked well on both old and newer SID chips, and was ripped by a couple of others to incorporate into their own demos. One of the members of Bomb-the-Bass called me 2-3 years later to ask about it.

    ReplyDelete
  16. On my website you'll see similar texts, write what you think. SennaGammour

    ReplyDelete
  17. Being a QuickBooks user if you are residing in Oregon then you are welcome to get benefitted with our QuickBooks Payroll Support Phone Number 1-833-780-0086. Dial to us, if you find yourself stuck with error code. For More Visit: http://theqbpayroll.mystrikingly.com/blog/quickbooks-payroll-support

    ReplyDelete
  18. I glanced through the article and found it assuredly pertinent to my engrossment. Certainly these apps might turn out to be beneficial for a majority of neophytes looking for resources to learn and enhance their skills
    Spoken English Speaking | English speaking app

    ReplyDelete
  19. Do you have the D64 file for this? Could you give me a link?
    http://musicinit.com/fastfingers.php

    ReplyDelete
  20. Worried about QuickBooks Support and suggestion ? if you are not able to fix QuickBooks error,get in touch with QuickBooks expert for instant solution.
    Dial our toll-free Quickbooks tech support 1-844-908-0801

    ReplyDelete
  21. By dialing on our QuickBooks Error Support Phone Number 1-833-325-0220 and you will be responded back with customer-oriented results.

    ReplyDelete
  22. Nice Blog!
    Fix QuickBooks error with Our QuickBooks expert Dial on Our toll free Number For instant and Quick Solution.
    Click Here to Know How to fix QuickBooks error code 80070057 1-844-908-0801

    ReplyDelete

  23. Nice Blog!
    Fix QuickBooks error with Our QuickBooks expert Dial on Our toll free Number For instant and Quick Solution.
    Click Here to Know Quickbooks Support Number+1-855-511-6911

    ReplyDelete
  24. It’s very informative and you are obviously very knowledgeable in this area. You have opened my eyes to varying views on this topic with interesting and solid content and call us :- 1-855-511-6911 Quickbooks Enterprise Support Number

    ReplyDelete
  25. Nice Blog !
    While being surrounded by such frightful coronavirus emergency when the whole world has been affected by this pandemic, still our diligent QB technicians are working by 24*7, day and night to support you. By connecting to our QuickBooks Payroll Support Phone Number 1-855-6OO-4O6O.

    ReplyDelete
  26. It is really interesting and nice blog poster.keep posting. Thanks for sharing.Proven ways to rank higher on Google Search result, Seo on page keyword research and content intimation and how to increase your website domain authority.

    best digital marketing agency in chennai|blog | fdm chennai | Best SEO Services in Chennai | digital marketing agencies in chennai | digital marketing consultants in chennai | Website designers in chennai

    ReplyDelete

  27. Thanks for sharing great information. I always love to read and spread this kind of information that is unique and really informative. The Cow Milk Delivers Farm Fresh Pure Cow Milk in Gurgaon at the Doorstep.
    For Info Visit us:-
    Cow Milk Home Delivery In Gurgaon
    Pure Milk Gurgaon
    Pure Cow Milk In Gurgaon

    ReplyDelete
  28. This comment has been removed by the author.

    ReplyDelete
  29. This was a great post. what you said is really helpful to me and it was really interesting as well. Keep up with your good work. Instant Approval DoFollow Travel Blog Commenting Sites

    ReplyDelete
  30. Hey! I hope you are doing well. In case you are looking for the best technical service in New Jersey, then look no further than QuickBooks Customer Service Number in New Jersey +1-844-442-1522.

    ReplyDelete

  31. Hey! I hope your working with QuickBooks is going great. If not, then dial QuickBooks Customer Service Number in Oregon +1-844-442-1522 and get the best technical assistance from accredited professionals.

    ReplyDelete
  32. Hey! Great work. If you are looking for reliable customer support, dial QuickBooks Customer Service Number in Pennsylvania +1-844-442-1522 for immediate help.

    ReplyDelete
  33. whatever kind of issues users are preoccupied with. They can get effective Instant Solution ✆ QuickBooks Payroll Support Phone Number by dialling us QuickBooks Payroll Support Phone Number at |+1(844)233-3033 For More Visit: https://247quikbooks-support.com/quickbooks-payroll-support-phone-number/

    ReplyDelete
  34. If confronting any sort of technical glitch in the software. Resolve it by calling on QuickBooks POS Support Number|+1(844)233-3033. Our learned & Experienced QuickBooks professionals are always presented to offer technical help. For More Visit: https://247quikbooks-support.com/quickbooks-pos-support-phone-number-usa/

    ReplyDelete
  35. Troubleshoot canon printer won't connect to wifi error quickly with the help of our highly skilled team. Our technicians are very experienced and they resolve your error very quickly. For more information you can check out our website canon printer offline.

    ReplyDelete
  36. Well explained and informative blog. In these challenging times, we urge you to stay home and stay safe and dial +1(844)233-3033 QuickBooks Support Phone Number whenever you face any technical issue in QuickBooks. For more details visit:https://247quikbooks-support.com/quickbooks-technical-support-phone-number/

    ReplyDelete
  37. nice post!
    Worried About QuickBooks Support ?Get in touch with QuickBooks expert for instant solution.
    Click Here to Know how to fix Quickbooks error h202 1-844-514-7111

    ReplyDelete
  38. Get Your Error and Problem Solve With QuickBooks Expert 24*7 live.
    Dial QuickBooks support Phone Number Florida to get in touch for
    More Details Dial : 1-844-514-7111

    ReplyDelete
  39. Very well explained and informative blog click here for Quickbooks Support Phone Number Tenesee and for more detail dial on our support number 855-756-1077


    Very well explained and informative blog click here for Quickbooks Customer Support Phone Number Tennesee and for more detail dial on our support number 855-756-1077


    Very well explained and informative blog click here for Quickbooks Customer Service Phone Number Tennesee and for more detail dial on our support number 855-756-1077


    Very well explained and informative blog click here for Quickbooks Customer Service Number Tennesee and for more detail dial on our support number 855-756-1077

    ReplyDelete
  40. Very well explained and informative blog click here for Quickbooks Support Phone Number Washington and for more detail dial on our support number 855-756-1077


    Very well explained and informative blog click here for Quickbooks Customer Support Phone Number Washington and for more detail dial on our support number 855-756-1077


    Very well explained and informative blog click here for Quickbooks Customer Service Phone Number Washington and for more detail dial on our support number 855-756-1077


    Very well explained and informative blog click here for Quickbooks Customer Service Number Washington and for more detail dial on our support number 855-756-1077

    ReplyDelete
  41. Very well explained and informative blog click here for Quickbooks Support Phone Number illnois and for more detail dial on our support number 855-756-1077


    Very well explained and informative blog click here for Quickbooks Customer Support Phone Number illnois and for more detail dial on our support number 855-756-1077


    Very well explained and informative blog click here for Quickbooks Customer Service Phone Number illnois and for more detail dial on our support number 855-756-1077


    Very well explained and informative blog click here for Quickbooks Customer Service Number illnois and for more detail dial on our support number 855-756-1077

    ReplyDelete
  42. nice post!
    Worried About QuickBooks Support ?Get in touch with QuickBooks expert for instant solution.
    Dial QuickBooks Support Phone Number San Francisco +1-888-603-9404

    ReplyDelete
  43. HI..... Magnetic Post .
    If you are looking for reliable drone service , dial Drone Photography And Videography (609) 992-1746

    ReplyDelete
  44. This Article is Really Fantastic And Thanks For Sharing The Valuable Post..
    Issues With Quicken Software Dial QuickBooks Support Phone Number ! Get Instant Help and Support

    ReplyDelete
  45. Hey! Outstanding blog. Your blog has all the required information that I was looking for. Moreover, you can contact QuickBooks Payroll Support Phone Number +1-877-751-0742 for the resolution of QuickBooks problems. The team at QuickBooks Support Phone Number +1-877-751-0742 are available 24/7 for you.

    ReplyDelete
  46. Hey! Well-written blog. I love your writing skill. Keep it up. For managing business accounts, use QuickBooks Enterprise software. In case you face any technical issue, dial QuickBooks Enterprise Support Phone Number +1-877-751-0742 and get your issues resolved quickly. Our service at QuickBooks Support Phone Number +1-877-751-0742 is open around-the-clock for their customers.

    ReplyDelete
  47. Nice Blog With Full of Knowledge
    Thanks For Sharing.....
    If you are searching for genuine QuickBooks Customer Service dial QuickBooks Support Phone Number +1 877-751-0742 for immediate help .Our Quickbooks Support Phone Number is available 24*7.

    ReplyDelete
  48. Looking forward for more informative post from you. If you want to teach your kids with apps and online activities you have to check out this. The Learning Apps

    ReplyDelete
  49. Hi! If you need technical help regarding QuickBooks issues, dial QuickBooks Support Numberdial tollfree number +1-800-754-6180 for help.

    ReplyDelete
  50. Hey! If you are looking for the authentic help for QuickBooks Payroll issues, then look no further than QuickBooks Payroll Support Numberdial tollfree number +1-800-754-6180 for help.

    ReplyDelete
  51. Hi! If you need technical help regarding QuickBooks Tech Support issues, dial QuickBooks Tech Support Number dial tollfree number +1-800-754-6180 for any help.

    ReplyDelete
  52. Hey! If you are looking for the authentic help for QuickBooks Enterprise issues, then look no further than QuickBooks Enterprise Support Number dial tollfree number +1-800-754-6180 for help.

    ReplyDelete
  53. You can get Apple-certified repairs and service at the Apple Store or with one of our Apple Authorized Service Providers.
    mobile phone repair in Niles
    Worked as a Senior SEO & Digital & Social Media & Graphics Design & cpa & Drop shipping & Video Editing And Youtube & Web Design And Development & Affiliate Marketing trainer at BITM (BASIS Institute of Technology & Management) since 2014-2018. Successfully completed 50+ SEO batches, 20+
    Affiliate Marketing batches and 30+ workshop on Freelancing under SEIP (Skills for Employment Investment Program).
    Best Graphic Design training in Bangladesh
    Free bangla sex video:careful

    ReplyDelete
  54. Gir AmritPhal is one of the biggest suppliers of organic & natural A2 Cow Milk in Delhi. Buy fresh cow milk online, buy quality a2 cow milk online, buy fresh a2 milk online at the best price.

    ReplyDelete
  55. I am here to give my testimony about Dr Ebhota who helped me.. i want to inform the public how i was cured from (HERPES SIMPLEX VIRUS) by salami, i visited different hospital but they gave me list of drugs like Famvir, Zovirax, and Valtrex which is very expensive to treat the symptoms and never cured me. I was browsing through the Internet searching for remedy on HERPES and i saw comment of people talking about how Dr Ehbota cured them. when i contacted him he gave me hope and send a Herbal medicine to me that i took for just 2 weeks and it seriously worked for me, my HERPES result came out negative. I am so happy as i am sharing this testimony. My advice to you all who thinks that there is no cure for herpes that is Not true just contact him and get cure from Dr Ebhota healing herbal cure of all kinds of sickness you may have like (1) CANCER,(2) DIABETES,(3) HIV&AIDS,(4) URINARY TRACT INFECTION,(5) CANCER,(6) IMPOTENCE,(7) BARENESS/INFERTILITY(8) DIARRHEA(9) ASTHMA(10)SIMPLEX HERPES AND GENITAL(11)COLD SOREHERPES. he also cure my friend from cervical cancer Email: drebhotasoultion@gmail.com or whatsapp him on +2348089535482

    ReplyDelete
  56. I am here to give my testimony about Dr Ebhota who helped me.. i want to inform the public how i was cured from (HERPES SIMPLEX VIRUS) by salami, i visited different hospital but they gave me list of drugs like Famvir, Zovirax, and Valtrex which is very expensive to treat the symptoms and never cured me. I was browsing through the Internet searching for remedy on HERPES and i saw comment of people talking about how Dr Ehbota cured them. when i contacted him he gave me hope and send a Herbal medicine to me that i took for just 2 weeks and it seriously worked for me, my HERPES result came out negative. I am so happy as i am sharing this testimony. My advice to you all who thinks that there is no cure for herpes that is Not true just contact him and get cure from Dr Ebhota healing herbal cure of all kinds of sickness you may have like (1) CANCER,(2) DIABETES,(3) HIV&AIDS,(4) URINARY TRACT INFECTION,(5) CANCER,(6) IMPOTENCE,(7) BARENESS/INFERTILITY(8) DIARRHEA(9) ASTHMA(10)SIMPLEX HERPES AND GENITAL(11)COLD SOREHERPES. he also cure my friend from cervical cancer Email: drebhotasoultion@gmail.com or whatsapp him on +2348089535482

    ReplyDelete
  57. Hello Friend am so happy to give this testimony about an Africa herbalist doctor called Dr Ogudugu who save my life from a herpes virus that almost took my life away, Never in my life did I think herpes virus could be cured by a herbal medicine, Thank you lord for giving me a second chance so am using this medium to reach the life of hundreds of people currently facing such diseases all hope is not lost. How ever chronic is the sickness or disease Dr Ogudugu will cure you permanently from it for i am a living testimony of his miraculous work and you can get in touch with this doctor via Email: greatogudugu@gmail.com or WhatsApp him +2348063739701
    I will forever be thankful to you Dr Ogudugu, God bless

    ReplyDelete
  58. Get the step by step instruction to fix Quickbooks Script Error Code 0 easily. Then you must read the full blog to gram the information.


    Related Article:
    QuickBooks Company File Not Found | Quickbooks Error 6144 82 | Update QuickBooks Desktop

    ReplyDelete
  59. Gir AmritPhal provides you one of the best quality, organic, and tasty Cow Milk delivery in Delhi. Get 100% pure & fresh milk delivered to your doorstep.

    ReplyDelete
  60. Wow, so beautiful and wonderful post! Thanks for giving an opportunity to read a fantastic and imaginary blog. It gives me lots of pleasure and interest. Thanks for sharing. If you need any technical support For QuickBooks Error 80029c4a in QuickBooks, click here, QuickBooks Error 80029c4a for best solution.

    ReplyDelete
  61. Excellent information Providing by your Article, Please post some more related topics.
    Biomanix with izon code in Dubai

    ReplyDelete
  62. This is Very very nice article. Everyone should read. Thanks for sharing. Don't miss WORLD'S BEST GAME 👉 MotocrossBeachBikeStuntRacingGames

    ReplyDelete
  63. Without data, you might not be able to run a business. Quickbooks allows you to manage your data and create backup of your data. But, sometimes you may see Quickbooks unable to create the backup of the company file- error.

    ReplyDelete
  64. This is so amazing article i got useful information from your blog . thanks for sharing such as information with us . you can also benefit QuickBooks Accounting software at quickbooks support phone number

    ReplyDelete
  65. your article most beneficial for me .i m waiting other article. thanks for sharing with us you can also get information about it quickbooks customer service phone number

    ReplyDelete
  66. Its Great Article thanks for sharing this type wonderful information please update in future again and again .if you are looking accounting service you can get by this at

    quickbooks support phone number

    ReplyDelete

  67. Thanks for sharing such useful information with us. I hope you will share some more info about your blog. Please keep sharing. We will also provide QuickBooks Support Phone Number for instant help.

    ReplyDelete
  68. I am looking for this informative post thanks for share it. We have an online store for liposuction Instruments. We are offering worldwide free shipping on every order.
    Johnnie Lok
    Syringe Snap Lock
    Syringe Tip Caps
    Toomey To Luer Lock Cannula
    Autoclave Tray

    ReplyDelete
  69. We are looking for an informative post it is very helpful thanks for share it. We are offering all types of leather jackets with worldwide free shipping.
    LEATHER BOMBER JACKET
    SHEARLING JACKETS
    SHEEPSKIN JACKET
    SUPERHERO LEATHER JACKET

    ReplyDelete
  70. Totally loved your article. Looking forward to see more more from you. Meanwhile feel free to surf through my website while i give your blog a read.
    men shearling jacket
    women shearling jacket
    men shearling coat
    women shearling coat
    men bomber jacket
    women bomber jacket
    men suede jacket
    women suede jacket

    ReplyDelete
  71. Herpes is a serious and recurring disease which can't be cured through drugs or injections by the American doctors but the best way to deal with Herpes is by taking natural herbs medicine for it, I have read about DR EDAGHONGHON the great herbalist doctor who cure me from herpes with his powerful herbal medicine. I contacted him to know how he can help me and he told me never to worry that he will help me with the natural herbs from God! After 2 days of contacting him, he told me that the cure has been ready and he sent it to me via UPS SPEED POST and it got to me after 3 days! I used the medicine as he instructed me (MORNING and EVENING) and I was cured! it's really like a dream but i am so happy! for the people suffering from the following diseases, Cancer, hypothyroidism, Herpes, COPD, HIV, Arthritis, Hpv, Infections,Liver Disease,, Autoimmune Diseases, Parkinson's disease,,Lupus and more should contact him for his herbal medicine because i am a living testimony and i was cured of herpes and his medicine is legit. I sent him what he requested and he sent me his medicine which I took for 3 good weeks and today am out here with a negative result. When I went for the test I was so happy after going through his medication. you can reach him through his email: dr.edaghonghonherbalhome@gmail.com or call whatsapp number:+2349056731866 he will help you out.

    ReplyDelete
  72. Thanks for sharing such useful information with us. I hope you will share some more info about your blog. Please keep sharing. We will also provide QuickBooks Customer Service Number (855)587-4968 or instant help.

    ReplyDelete
  73. Thanks for sharing
    Village Talkies a top-quality professional corporate video production company in Bangalore and also best explainer video company in Bangalore & animation video makers in Bangalore, Chennai, India & Maryland, Baltimore, USA provides Corporate & Brand films, Promotional, Marketing videos & Training videos, Product demo videos, Employee videos, Product video explainers, eLearning videos, 2d Animation, 3d Animation, Motion Graphics, Whiteboard Explainer videos Client Testimonial Videos, Video Presentation and more for all start-ups, industries, and corporate companies. From scripting to corporate video production services, explainer & 3d, 2d animation video production , our solutions are customized to your budget, timeline, and to meet the company goals and objectives.
    As a best video production company in Bangalore, we produce quality and creative videos to our clients.

    ReplyDelete
  74. QuickBooks is one of the most popular accounting software that simplify your life as an entrepreneur. When you feel any issue regarding QuickBooks then you can call at
    quickbooks customer service number+1 855-437-6748

    ReplyDelete
  75. Hey! Nice Blog, I have been using QuickBooks for a long time. One day, I encountered QuickBooks Enterprise Support (855)756-1077 in my software, then I called QuickBooks Support Phone Number (855)885-8282. They resolved my error in the least possible time.

    ReplyDelete
  76. CL 4K UHD Video Player - HD video player for android – App

    CL 4K UHD Player- High Quality Video Player app allows you to watch your favorite movies, shows and other videos in Ultra HD quality. You can watch high quality videos from your device or SD card and stream from web. This app also works as whatsapp status downloader.

    Install CL 4K UHD Player- High Quality Video Player on your android device and enjoy 4K ultra HD videos anytime, anywhere. Best all format hd video player

    ReplyDelete
  77. Thanks for sharing such useful information with us. I hope you will share some more info about your blog. Please keep sharing. We will also provide QuickBooks Customer Service Number +1 888-471-2380 or instant help.

    ReplyDelete
  78. Hey! Excellent work. Being a QuickBooks user, if you are struggling with any issue, then dial QuickBooks Phone Number.+1 888-698-6548,SD. Our team at QuickBooks will provide you with the best technical solutions for QuickBooks problems.

    ReplyDelete
  79. Awesome blog!! Thank for providing excellent information. if you have any issues with QuickBooks Company File Not Found, you can go through the detailed steps mentioned in this article.

    ReplyDelete
  80. This is amazing post for Quickbooks user which is one of the best software for manipulating many accounting task . this software could be any issue . to resolve your issue connect with at QuickBooks Error PS060.

    ReplyDelete
  81. QuickBooks Database Server Manager have created a massive impact in the world of accounting and finances. It is now extremely preferred by most businesses to generate invoices thus helping small businesses run with authenticity. One great thing about QuickBooks is that its interface is so easy that anyone can use it without any hassle

    ReplyDelete
  82. Amazing Post I Enjoyed Reading your Post Its Amazing Thanks For Sharing The Experience!
    percetakan buku online di jakarta

    ReplyDelete
  83. Nice Article You Have Here! Buy Research Chemicals Online We Also Have Good Quality Research Chemicals For Sell.

    ReplyDelete
  84. Sage Payroll Support Number and Sage Fixed Assets Support Number Asset modules are accounting features for your Sage Business Management Accounting software. If you have already purchased Sage Business Management Accounting, then you do not need to spend more money on acquiring these two additional modules. You can use them free of charge along with your original platform. Sage Timeslips Support Number is an additional tool for those users who are not able to setup their account and not able to access their data. Sage Online Support Number is available to all users of the Sage products who need help installing, configuring, upgrading or resolving an issue with their software.

    ReplyDelete
  85. Nice Post. You present these principles very easily. We will definitely share this in our blog.
    https://pankajglobal.in/

    ReplyDelete
  86. It’s really an amazing blog great to get the relatives information through your site for all the people, I appreciate your efforts. Thank you for sharing your knowledge and experience with me.
    QuickBooks error code 6144 and 82 | QuickBooks error code 6189 | Merge vendors in QuickBooks desktop | Record a vendor refund in QuickBooks Desktop

    ReplyDelete
  87. This comment has been removed by the author.

    ReplyDelete
  88. Hello Nice Blog ! If you are searching accounting service then you can contact for instant help at Quickbooks Customer Service+1 717-844-9353

    ReplyDelete
  89. If you are looking more informations about quickbooks Software then , then dial Quickbooks Customer Support +18555484814 and talk to a support agent

    ReplyDelete
  90. Thanks for sharing such useful informations ! If you have big issue about your quickbooks software then you can call at
    Quickbooks Support +1 866-306-2642 for instant help.

    ReplyDelete
  91. This is really Nice blog ! . If you are looking for help with QuickBooks, Call at Quickbooks customer service for help with any sort of QuickBooks issue.

    ReplyDelete
  92. Thanks for sharing such important information ! If you have any query then our qualified technicians will provide you with quick solutions call at
    Quickbooks customer service number+1 855-548-4814

    ReplyDelete
  93. QuickBooks is effective and popular accounting software that helps you manage all the finance and accounting related tasks of business.if you have any questions related to their Quickbooks Software then contact our team at
    Quickbooks Customer Support+1 855-604-1500

    ReplyDelete
  94. This comment has been removed by the author.

    ReplyDelete
  95. QuickBooks is popular accounting software .It also tracks sales, accounts receivable, payroll, inventory, and much more Dialling
    Quickbooks Customer Support +1 855-377-7767 will provide answers to your questions

    ReplyDelete
  96. This comment has been removed by the author.

    ReplyDelete
  97. very good informations !To find a
    Quickbooks Customer Support for nearesr you dial toll free Number for quick assistance. +1 347-982-0046

    ReplyDelete
  98. Get Quickbooks Customer Support+18777555046 For Financial need for youe business

    ReplyDelete
  99. This comment has been removed by the author.

    ReplyDelete
  100. Nice Information ! ! For any further assistance related to Quickbooks , Visit at More-
    Quickbooks Customer Support+18554287237

    ReplyDelete
  101. Here is an amazing Blog Informations !If you are struggling with a QuickBooks issue, Dialing the number of the
    Quickbooks Customer Support +1 267-773-4333

    ReplyDelete
  102. You can get answers to all your Quickbooks questions ,dial Quickbooks Customer Support +1 888-272-4881 for live chat support from Quickbooks Customer Support 1 855-604-1500

    ReplyDelete
  103. QuickBooks is a very famous accounting software that can help you keep track of your expenses, income, and cash flow you can contact us
    Quickbooks Customer Support : +1 855-377-7767

    ReplyDelete
  104. Great information If you are looking kind of Regarding Quickbooks Help then Click at
    Quickbooks Customer Service +1 855-428-7237

    ReplyDelete
  105. QuickBooks is accounting software that provides you with various features for the upliftment of your organization.If you're struggling with your Quickbooks account and you need help, call customer service at Quickbooks Customer Service +1 855-377-7767

    ReplyDelete
  106. Quickbooks is a fantastic accounting software If you want to know more Quickbooks Knowledge then you can Click at Quickbooks Customer Service +18559411563 and get Solutions

    ReplyDelete
  107. This comment has been removed by the author.

    ReplyDelete
  108. Quickbooks customers can dial Quickbooks Customer Service +1 855-604-1500 To get all Solutions Of Your Provlems To get all Solutions Of Your Provlems

    ReplyDelete
  109. if you still want quick help from QuickBooks,, you can dial the QuickBooks helpline on
    QuickBooks Customer Service +18559411563 and talk to one of their representatives.

    ReplyDelete
  110. If you are facing issues while technical issues with Quickbooks Software You can contact Quickbooks Customer Service +18777555046and talk to one of their representatives.

    ReplyDelete
  111. Quickbooks is amazing software in the world. For more information about Quickbooks then dial Quickbooks customer service +1 602-362-8345 and get help from a professional.Quickbooks is amazing software in the world. For more information about Quickbooks then dial Quickbooks customer service +1 602-362-8345 and get help from a professional.

    ReplyDelete
  112. To renew your QuickBooks Payroll Subscription, log in to your QuickBooks account and navigate to the subscription management section. Select the option to renew your payroll subscription and follow the prompts to complete the renewal process.

    quickbooks error h101
    QuickBooks Script Error
    Renew QuickBooks Payroll Subscription

    ReplyDelete