Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!


1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


aregee

Member Since 06 Oct 2009
Offline Last Active May 29 2015 09:52 AM

Topics I've Started

Too clever...?

20 May 2015 - 05:36 PM

Just writing a simple string tokeniser from scratch, when I came to a "clever" realisation when it comes to bounds checking.

 

Say you have a string of a certain length, and you want to find a token within a section of the string, you would provide an index for the first character position you want to search from and another index for the last character in the string you will be looking.

 

Then you need to verify the sanity of these values.

 

The immediate way to do that would be to just check each first and last bounds to the length of the string and check that the last bound index is not before the first.

 

Then I came up with the following optimisation:

static inline int findToken(const int firstIndexInclusive, const int lastIndexExclusive,
                     const std::string string, const std::string oneOfChars) {

    unsigned long stringLength = string.length();
    
    if ((firstIndexInclusive < 0) || (lastIndexExclusive > stringLength) || (lastIndexExclusive < firstIndexInclusive)) {
        return -1;
    }
    
    //searching for occurence of any of the 'oneOfChars' here
    
    return 0;
}

Just three tests accounts for all the boundaries that you would normally check against, which in normal cases I would probably have 5 checks for.

 

After the first bit of cleverness subsided, it came to me that the readability goes down, the optimisation is rather minor unless if I process a lot of text, although the time I spent making this was not much.  Besides, I think that if you do obvious optimisations while you write code, that is a good thing, but the readability factor is an issue to me.

 

What do you think?  Is this premature optimisation?


New to templates - Compiler can't find member name

19 May 2015 - 10:03 PM

I am trying to make a circular doubly linked list, and thought it was a good idea to implement it as a template, since I will be using this kind of lists in my project.

 

The problem is, that while I think to my understanding that I have done everything right, my compiler beg to differ.

 

The error messages I get are:

 

- "Unknown type name 'node'"

- "Expected member name or ';' after declaration specifiers"

 

I get these two messages for each of the offending lines, and everything seems right to me.  I am sure there is something I am lacking in understanding or something.

 

My template class:

#include <stdio.h>

template <typename T>
class Node {

private:
    T *mData;
    
    Node<T> *mPreviousNode;
    Node<T> *mNextNode;
    
    Node<T> *mChildNode;
protected:
    
public:
    Node();
    ~Node();
};

template <typename T>
Node<T>::Node() {
    mData = nullptr;
    mPreviousNode = nullptr;
    mNextNode = nullptr;
    mChildNode = nullptr;
}

template <typename T>
Node<T>::~Node() { }

The header class with the offending lines:

#include <stdio.h>

class Path {
private:
    Node<Point> *mPointListHead; // <<---- THIS LINE,
    Node<Point> *mPointListTail; // <<---- AND THIS LINE
    
protected:

public:
    Path();
    ~Path();
    
    void addPoint(float x, float y, float z);
};

The Implementation for the class:

#include "Node.h"
#include "Point.h"
#include "Path.h"

Path::Path() {
    mPointListHead = nullptr;
    mPointListTail = nullptr;
}

Path::~Path() {
}

void Path::addPoint(float x, float y, float z) {
    printf("Adding point\n");
}

The header file for the Point class just for reference:

#include <stdio.h>

class Point {
private:
    float mX, mY, mZ;
    float mR, mG, mB, mA;
    
protected:
    
public:
    Point();
    Point(float x, float y, float z);
    Point(float x, float y, float z, float r, float g, float b, float a);
    ~Point();
};

The implementation of Point:

#include "Point.h"

Point::Point() : Point(0.0f, 0.0f, 1.0f) { }

Point::Point(float x, float y, float z) : Point(x, y, z, 1.0f, 1.0f, 1.0f, 1.0f) { }

Point::Point(float x, float y, float z, float r, float g, float b, float a) {
    mX = x; mY = y; mZ = z;
    mR = r; mG = g; mB = b; mA = a;
}

Point::~Point() {
    
}

Thanks for any help with this, and yes, I know that classes are private by default.

 

EDIT: The weird thing is that the "intellisense" (*) kind of thing sometimes seem to colour the keywords like it understand the names, but when I try to compile again, it forgets them again.  When the names are in the colours that shows that the IDE knows the class names, I can also start typing and get the correct autocomplete suggestions.  Also this goes away if I try to compile.  I am using the latest Xcode by the way, but I am pretty sure it is me goofing up, not the IDE/compiler.

 

(*) I don't know what name Apple has for the "intellisense".


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.

PARTNERS