Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


aregee

Member Since 06 Oct 2009
Offline Last Active Nov 03 2014 04:10 AM

Topics I've Started

For-loop-insanity

01 September 2014 - 10:31 PM

In a careless thought to make the data type as small as possible, the compiler complained (naturally) of me using a constant that was too big for the type I was testing against:

    for (uint8_t j = 0; j < (1 << 8); j++) {
        ...
    }

Which gave me the idea to come up with this masterpiece:

    for (uint8_t test = 0; test <= 255; test++) {
        printf("%i\n", test);
    }

Any DSP gurus - PDM to PCM - noise/aliasing/spectral leakage problem?

01 September 2014 - 07:58 PM

For the non-expert:
DSP = Digital Signal Processing
PDM = Pulse Density Modulation
PCM - Pulse Code Modulation
 
I am struggling with what is sounding like an evenly distributed hiss on top of otherwise very good sounding audio when decoding pulse density modulated audio to pulse code modulated audio.
 
The bitstreams I am working with are 1 bit 2.8225 Mhz PDM, and I am "resampling" it to 16 bit 44.1 kHz PCM.  That translates to about 64 one bit samples per 16 bit PCM samples at 44100, thus I am using a 64 order window function to make PCM out of PDM.
 
How I am processing the audio is like this:
 
First I am making a precalculated window function like this:
 

        for (int i = 0; i < 64; i++) {
            fir64Coff[i] = (double_t)(1 << 10);
            //Hanning Window (less noise than hamming?
            fir64Coff[i] *= 0.5 * (1 - cos((2 * M_PI * i)/ (64 - 1)));


            //Hamming Window
//            fir64Coff[i] *= 0.54 - 0.46 * cos((2 * M_PI * i) / (64 - 1));
            
            //Nuttall Window
//            fir64Coff[i] *= 0.355768f - 0.487396*cos((2*M_PI*i)/(64 -1)) + 0.144232*cos((4*M_PI*i)/(64-1))-0.012604*cos((6*M_PI*i)/(64-1));
  
            //Cosine Window
//            fir64Coff[i] *= sin((M_PI * i)/(64-1));


   //Blackman Harris            
//            double_t w = (2 * M_PI * i) / 64;
//            fir64Coff[i] *= 0.422323 - 0.49755 * cos(w) + 0.07922 * cos(2 * w);
        }
 
Hamming/Hanning sounds the best of the window types I have tried.
 
Here is how I generate PCM from PDM:  (Be warned this is just some pilot tinkering.)
 

- (uint64_t)getBytes:(void *)buffer sampleCount:(long unsigned)count {


    if (mIsEndOfSong) {
        return 0;
    }


    [mutex lock];


    int16_t *sampleBuffer = (int16_t *)buffer;
    
    for (uint32_t currentSample = 0; currentSample < count; currentSample++) {
        uint64_t testLeft = 0;
        uint64_t testRight = 0;


        int64_t sumLeft = 0;
        int64_t sumRight = 0;


        uint8_t coefficientIndex = 0;
        
        for (uint8_t i = 0; i < 8; i++) {
            if (currentBufferPos >= blockSize) {
                if (![self readChunk]) {  //Here I fetch left and right channel blockSize bytes (Usually 4096)
                    [mutex unlock];
                    return currentSample;
                }
            }
            
            testLeft = bufferLeft[currentBufferPos];
            testRight = bufferRight[currentBufferPos];
            
            for (uint8_t i = 0; i < 8; i++) {  //Two nested for loops, 8 * 8 = 64 bits, lsb first per byte
                if ((testLeft & 0x01) == 0x01) {
                    sumLeft += fir64Coff[coefficientIndex];  //These are the pre-calculated window values
                }
                else {
                    sumLeft -= fir64Coff[coefficientIndex];
                }
                
                if ((testRight & 0x01) == 0x01) {
                    sumRight += fir64Coff[coefficientIndex];
                }
                else {
                    sumRight -= fir64Coff[coefficientIndex];
                }
                
                testLeft >>= 1; //Next bit
                testRight >>= 1;
                
                coefficientIndex++;
            }
            
            currentBufferPos++;  //next byte
        }


        sampleBuffer[(currentSample << 1) + 0] = (int16_t)sumLeft;
        sampleBuffer[(currentSample << 1) + 1] = (int16_t)sumRight;
    }
    
    [mutex unlock];
    return count;
}
 
Pretty simple, actually, and it sounds great - except for the noise.  I am not sure what I am doing wrong.  I am sure super audio is not supposed to have varying degree of noise in them.  I have read that when audio is being sampled, a noise shaping function is being used, and noise generated during this process is pushed up into the inaudible frequency range.  I am wondering if the noise I am hearing can be this high frequency noise being aliased back into the perceptible frequency area.
 
Does anyone have any tips for me, how to get rid of the noise?  I tried to make a low pass filter too, but that made the noise even louder and with no music at all, so there is probably something I did wrong.
 
Here is the function I made for that, if it can be of any help:
 

- (void)lowPassFIR:(double_t*)firBuffer withSampleRate:(uint64_t)Fs cutOffFrequency:(uint64_t)Fc filterLength:(uint64_t)M {
    M = M -1;
    double_t Ft = (double_t)Fc / (double_t)Fs;


    double_t sum = 0.0f;
    
    for (uint64_t i = 0; i < M; i++) {
        if (i != ((double_t)M / 2)) {
            firBuffer[i] *= sin(2.0f * M_PI * Ft * (i - ((double_t)M / 2.0f))) / (M_PI * (i - ((double_t)M / 2.0f)));
        }
        else {
            firBuffer[i] *= 2.0f * Ft;
        }
        
        sum += firBuffer[i];
        printf("%f\n", firBuffer[i]);
    }
    printf("Sum: %f\n", sum);
}
 
Edit: it is worth mentioning that I am trying to learn DSP, but I am an utter noob in this area.  I have a vague understanding, but not all the pieces are in place yet, so I think I have done pretty well, considering I have just jumped into this.  This is also something I am doing just for fun and to learn, and weirdly something as recognised as VLC can't play either.
 
Edit2: I have a feeling the noise comes because I am not properly "moving" the window, just taking a weighted average starting at every 64 bits, but I am trying to reduce the massive amount of processing I need to do if I would do a moving average of every 64 bit bits before I have produced even one PCM sample.  That would make 64 * 64 = 4096 loop iterations for each PCM sample, 4096 * 44100 = 180.633.600 iterations per second...  I think my computer would have hiccups long before that.
 
Another theory I have, is that I am just discarding the remainder of the double after a full integer, and that is generating some dithering noise.
 
Edit3: Just got an idea to get completely rid of the if-sentences in the inner loop.  I can just make a lookup table for that as well...  That means I can get rid of the whole inner loop completely.

Copy/paste fail

22 August 2014 - 06:03 PM

I am not sure if this is the right place, but...
 
This is a tale of copy and paste snafus.  (Not sure if this is the right term, but it sounds fancy...)
 
I was making CRC checking in my FLAC player, and I was copying a minor part of the CRC-8 part to make the CRC-16 part.  In the debugging I observed that all the generated values were in the range 0..255, but it was supposed to be 16 bit.
 
What I did was:
 
Implementation:
 
- (uint16_t)CRC16 {
    return mCRC16;
}
 
Definition:
 
- (uint8_t)CRC16;
 
Notice the mismatching return values of the definition and implementation.
 
What I didn't notice was the compiler complaining with a WARNING (not an error) that:
 
crc.png
 
So even though the method definition didn't match, the runtime was happy to use the "substitute" instead, providing me with wrong values.

Journals... purpose and guides?

22 August 2014 - 07:55 AM

Hi!

 

I was just wondering if there exists any guides here to write journals?  I also wonder the purpose and if there is any rules or similar I need to know about, or if it is meant to be some sort of personal space where you write about things that other people might be interested in?

 

Just to be sure I don't mess up anything if I decide to write something.

 

I did try to search, but I couldn't find anything obvious here to answer my questions.


I am looking for a list view in Cocoa to handle a massive amount of data

30 July 2014 - 01:59 PM

In my application, I am using a NSTableView that is connected to a NSArrayController.  In my case, I am loading absolutely everything into memory, which in itself is not really a problem.  It is really fast and responsive, but I am planning to use a database instead to make the data more persistent.

 

I am almost certain I remember a kind of view in the past, that you just specified how many items were in the view, so the view knew the amount to scroll, then the view would ask for the data it needed for the items that were visible, and discard everything else, if it wanted.  In this way, I don't need to keep everything in memory at once.

 

My problem is that I don't remember what it is called, nor can I find it, and lastly, I don't know what to search for.

 

I would probably not have much problems making such a thing myself, but it will be a lot more work. If there is something already existing, I'd rather use that.  Does anybody have any ideas?


PARTNERS