Shop OBEX P1 Docs P2 Docs Learn Events
Mono 16-bit sound player with declicking — Parallax Forums

Mono 16-bit sound player with declicking

Peter JakackiPeter Jakacki Posts: 10,193
edited 2009-01-25 17:20 in Propeller 1
I adapted "stereo.spin" as a quick hack (when do I get time to write software?) to play standard signed 16-bit PCM files in mono for a small keypad style sound track player that feeds into a PA system.

This is designed to be nice and simple to use so using a small 12-key keypad I key in the track number which displays on a 4-digit LED display and then I press the "#" button to PLAY/PAUSE. Could it be any simpler? The current MP3 CD player is very awkward and there is no way to key in multi-digit track numbers directly although I have used a bulky DVD player with a remote.

This software was initially integrated into FemtoBasic and tested on my iCONSOLE late last night to make sure it would do the job. The calling software skips the WAV header and just feeds the sound data to the buffers.

Now I'm putting a standard 35x38mm Propeller SD card module of mine into a plastic case with the keypad and display. This unit will be powered from the mixer and
output the audio straight from the RC DAC out via an RCA connector to the mixer although I might even buffer it with an opamp.

I will post the details of the complete unit and software once I'm done if anyone is interested.

I used free SWITCH software (www.nch.com.au/switch) to convert MP3 tracks to PCM uncompressed 22050Hz 16-bit MONO files which I loaded onto an SD card.

*Peter*

Comments

  • RaymanRayman Posts: 14,826
    edited 2008-07-15 15:50
    Does the declicking work?· A couple people have tried this with no success...
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2008-07-15 16:05
    The startup click is the result of the DAC output going from zero volts up to the value of the first sample. All I do is ramp up to 0.5VDD which is my null audio level before I output the signed samples. This switch-on ramp takes around 400ms although it could be much shorter.

    Of course it works [noparse]:)[/noparse]

    *Peter*
  • lonesocklonesock Posts: 917
    edited 2008-07-15 23:08
    Hi, Peter.

    Looks nice! (Unfortunately I only have the protoboard, no audio I/O as of yet, so I can't really test it, but I'm looking forward to doing so.)

    I've been working on some audio compression stuff, basically an extension of the ADPCM scheme used in the HSS (see this thread).

    The changes:
    1) adapt the power of 2 modifier each byte (add an offset, instead of using a fixed number 0-3), so you can use higher bit-depths source audio
    2) variable number of samples per byte (1,2,3,6,7) for a range of compression/quality tradeoffs
    3) the decoder does an averaging step (sounds better, better RMSE, at the expense of a lag of 1 sample. I should only do it for 1bit/sample levels, as it is not needed for the higher quality modes)
    4) multiple channels are supported (up to 8)

    I have a preliminary write-up, along with the C++ code and Windows executable for a compressor (loads WAV and OGG) & decompressor (saves WAV) on my site. Basically, it sounds OK at 3 samples per byte (6x compression), good at 2 (4x) and great at 1 (2x compression for 16-bit input sources). Depending on the output circuitry, the 4x compression might be transparent.

    If you are interested in using some compression, I'd be happy to adapt the code you gave (though I would be "flying deaf" wink.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    lonesock
    Piranha are people too.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2008-07-16 01:30
    Hi lonesock,

    Don't you have a resistor and capacitor? Even without buffering you should be able to feed it into computer style amplifier speakers.

    I had thought about both standard and custom compression but as it was a quick hack and SD cards are cheap I chose the simple approach. That doesn't mean I mightn't consider compression in future though.

    A further note in general to everyone about achieving clickless operation. My sound cog shuts down after it plays the file which means the DAC pin is floating. Since the PLAY routine ramps up from zero volts it is possible to introduce a click by virtue of a sudden large change in voltage. This is is easily fixed in my case by the inclusion of a bleed resistor across the DAC capacitor. Any high value is fine and it could range from 1M down to about 100K or so to ensure that the capacitor charge can bleed away after the cog releases the pin. If you keep the cog running then you can achieve the same thing by releasing the DAC pin between tracks and allowing it to bleed the charge through the resistor. There are other software methods too which I haven't tried yet in this short time but the main thing to avoid is the sudden voltage swing which short as it may be is always noticed.

    I have reduced files down to 11025Hz and still get quite good quality. Also, I did have some trouble with using 2GB cards but it looks like a sector size thing which I will sort out in the meantime.

    *Peter*
  • Bob Lawrence (VE1RLL)Bob Lawrence (VE1RLL) Posts: 1,720
    edited 2008-07-27 00:45
    Peter said...
    I will post the details of the complete unit and software once I'm done if anyone is interested.

    Good work. I look forward to your updates.

    I have been making a player (with Raymond wave/spin) that plays a wave file and shows Pedal Steel Guitar tab( number system for the notes to play) on a TV screen. i.e intro to a song. Eventually I need to load the tab from the SD card but so far it's hard coded in spin, but works. turn.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Aka: CosmicBob

    Post Edited (Bob Lawrence (VE1RLL)) : 8/30/2008 5:30:16 PM GMT
  • drazmodrazmo Posts: 21
    edited 2008-08-30 04:33
    Peter Jakacki said...
    The startup click is the result of the DAC output going from zero volts up to the value of the first sample. All I do is ramp up to 0.5VDD which is my null audio level before I output the signed samples. This switch-on ramp takes around 400ms although it could be much shorter.

    Of course it works [noparse]:)[/noparse]

    *Peter*

    I have used your declick function with Raymans ASM wav Player and it seems to remove the initial click when a file starts to play. I still have one pop when the board powers up but I can live with that. I moved around the waitcnt and it seems to work. The problem I have now is when the file ends and the cog stops you hear a loud pop. I have tried to reverse the declick function to from .5vdd to 0....but no luck..... here is what I have so far.. I am trying to play multiple wav files in sequence so the cog starts up plays the file and then stops.

    Code that removes pop on file startup.
    setup
    
              'setup counters
            OR CountModeR,OPinR
            MOV CTRA,CountModeR
            OR CountModeL,OPinL
            MOV CTRB,CountModeL
    
            'setup output pins
            MOV DMaskR,#1
            ROL DMaskR,OPinR
            OR DIRA, DMaskR
            MOV DMaskL,#1
            ROL DMaskL,OPinL
            OR DIRA, DMaskL
    
    
            ' Fast lane....
            mov val, #0
    :declick                            ' ramp up the audio DC output voltage from 0 to midway (0.5 VDD)
            'waitcnt nexttime, delta
            mov nexttime, cnt
            add nexttime, delay
    
            waitcnt nexttime, delta
           
            mov frqa, val
            mov frqb, val
            add val,fadeval
            cmp val,midval wz          ' midway yet?
      if_ne jmp   #:declick
                    
            'Wait for SPIN to fill table
            MOV WaitCount, CNT
            ADD WaitCount,BigWait
            WAITCNT WaitCount,#0
            'setup loop table
            MOV LoopCount,SizeBuff  
            'ROR LoopCount,#1    'for stereo
            MOV pData,pData1
            MOV nTable,#1
            'setup loop counter
            MOV WaitCount, CNT
            ADD WaitCount,dRate
    
    
    MainLoop
          ......
    
    




    Code to ramp down on the way out....DOES NOT WORK

            JMP #MainLoop                
    Done
        
            mov val, frqa
            mov ctr,$1FF
    :declick2
            mov nexttime, cnt
            add nexttime, delay
            waitcnt nexttime, delta
           
            mov frqa, val
            mov frqb, val
            sub val,fadeval            ' Subtract fadeval to ramp down to 0v
            sub ctr,#1
    
            cmp ctr,#0 wz
            if_z jmp #:declick2
     
    'now stop
            COGID thisCog
            COGSTOP thisCog  
    
    
  • Bob Lawrence (VE1RLL)Bob Lawrence (VE1RLL) Posts: 1,720
    edited 2009-01-25 17:20
    Peter said...
    I will post the details of the complete unit and software once I'm done if anyone is interested.

    Peter,

    How's your project going?

    Bob

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Aka: CosmicBob
Sign In or Register to comment.