Search

Kernel Panic

It may be possible that I don't know anything.

Thoughts on Open Source

opensource-svg

I used to not understand open source.

Why would people give away their source code for free? Going through the software revolution of the 90s, Microsoft was the king of software. I followed the Microsoft’s decimation of WordPerfect, Borland, Lotus 1-2-3 and Netscape as a kid. And Microsoft didn’t give away software for free, no, let alone source code! Microsoft charged folks for Office, Windows, Visual Studio, etc. To their credit, they still do to a certain extent. So to me, it all seemed counter-intuitive – something that was free, in my mind, would not see any quick progress due to the lack of economic motivation behind it. My overall train of thought could be summarised by this grumpy nerd’s post.

Then Linux Torvalds came along with this :

Hello everybody out there using minix –

I’m doing a (free) operating system (just a hobby, won’t be big and professional like gnu) for 386(486) AT clones. This has been brewing since april, and is starting to get ready. I’d like any feedback on things people like/dislike in minix, as my OS resembles it somewhat (same physical layout of the file-system (due to practical reasons) among other things).

— Linus Torvalds

And it’s amazing how others have contributed to the project ever since. Linux is probably the most successful example of open-source software. From the Linux kernel, countless distributions have emerged. Heck, even Android has the Linux kernel in it. Red Hat, CentOS, Ubuntu, Debian, Linux Mint they all share the linux kernel, which is actively being maintained by the Linux Foundation.

There’s a lot of open source software out there, and it’s all a beautiful mess. Companies leveraging on open-source software have been successfully built. Red Hat is a prime example of this, which generates revenue through support and training contracts. http://www.zdnet.com/article/red-hat-nearing-1-billion-in-revenue-not-bad-for-free-software/ And did you know that WordPress, the blog software that you are reading this on, is open-source?

The problem with proprietary software is this : When you don’t know what’s going on, you don’t know what’s going on. Proprietary APIs usually hide the implementation details of a function, so you are at the mercy of whoever holds the proprietary software implementation. You would be in danger even. I’m sure Snowden would agree. With open source, all the implementation details are out there, whether you want to understand it or not. Furthermore, with proprietary software, once the company decides that it is no longer in their financial interests to continue with the work, it is thrown away.

I’ve concluded that to make large scale software without a whole Fortune 500 company like Microsoft or Google behind you, open source is the way to go. I use ZeroMQ in my work, and this is a great example of this. The author has successfully built a community from which many other projects have sprung.  Once folks find that the open source code is useful to them, they will have it in their hearts to contribute back. Even if it is just fixing a bug or two.

My other open source loves are CSound and  AudioKit , all great audio programming open source projects from which one can learn. AudioKit is fairly new, but has enjoyed quick growth due to many developers wanting a Swift audio development framework (pun intended).  It was the CSound code that inspired me to delve into DSP code.

Revenue for the little guy? I’d like to think of somehow who buys stuff I make as paying me to keep it going. It is not easy maintaining a piece of software amidst the ever-changing tech landscape.I would say it takes more energy to maintain software than to shit one out.

Open source is simply a developmental methodology that was ahead of its time. It’s a methodology that places community over software. It’s a reflection of the human need to contribute and make a difference. I that software, like nature, given enough time undergoes evolution. Great software stays and gets better with time.

[ERRFMT] using Poco Logger

When using the poco logger to log values like this, many at times the logged value is displayed as [ERRFMT]. The poco logger is saying that it does not recognize the input parameter as the one being specified by the identifier. Poco is extremely finicky regarding this!

For example,

float stddev = 3.53525f
 m_log.debug("Std dev = %f", stddev);

Output

Std dev = [ERRFMT]

The correct formatting to be used for Poco :

bool %b
char %c
int %d, %i
unsigned %u
short %hd
unsigned short %hu
long %ld
unsigned long %lu
long long %Ld
unsigned long long %Lu
unsigned (octal) %o
unsigned (hex) %x, %X
double %f, %e, %E
float %hf, %he, %hE
std::string %s
std::size_t %z

Hence the example above should be :

 m_log.debug("Std dev = %hf", stddev);

Printf in C automatically promotes variables to the appropriate format for print out, which is why you don’t have this hassle when using printf.

Using libtiff for luminance/grayscale images

Libtiff is a library for reading and writing TIFF, a small collection of tools for doing simple manipulations of TIFF images on UNIX systems.



#include 
#include 

const int width = 256;
 const int height = 256;
 const int sampleperpixel = 1;
 uint8_t image[height*width];

int main()
 {
 for (int r=0; r < height; r++) {
 for (int c=0; c < width; c++) {
 image[r*width+c] = (r + c) % 256;
 }
 }

TIFF *tif = TIFFOpen("output.tif", "w");
 TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
 TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
 TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, sampleperpixel);
 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
 TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
 TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
 TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
 // TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, width*sampleperpixel));

for (int r=0; r < height; r++) {
 TIFFWriteScanline(tif, &image[r*width], r, 0);
 }

TIFFClose(tif);
 }

For TIFFTAG_PHOTOMETRIC, you need to set it to PHOTOMETRIC_MINISBLACK for the desired results using 1 sample per pixel, 8 bits per sample. This is for grayscale images with only a single channel.

The default from the libtiff examples is PHOTOMETRIC_RGB. This is for conventional images with 3 channels RGB.

Download libtiff here:  http://dl.maptools.org/dl/libtiff/

Geodetic vs Geocentric Coordinates

This is the simplest visualisation / explanation I could find.

450px-geocentric_vs_geodetic_latitude-svg

AP refers to geocentric coordinates. Reference point is always A, the centre of the earth.
IP refers to geodetic coordinates, where IP is the normal (perpendicular) to the plane of where you are. Reference point I differs depending where on the earth you are (P).

Source: https://en.wikipedia.org/wiki/Geodetic_datum

C++ Equivalents of some Matlab Functions

https://github.com/lppier/DSPFunctions

Here are some C++ versions of Matlab DSP Functions, so that you can be saved the trouble of coding them from scratch. I will add more as time goes by.

Finding Suitable FFT Numbers

sfft5

Many high quality FFT libraries support fast implementations for small primes. (2,3,5,7). I’ll use CUDA fft here as an example.

When you have say  an array of 18000 samples d_data, you might not want to do this:

nfft = 32768; 
cudafftPlan1d(&m_plan, nfft, CUFFT_C2C, 1); 
cufftExecC2C(m_plan, d_data, d_data, CUFFT_FORWARD);

Especially if you are doing many, many iterations of this.

Instead, you can use a method to find the closest fft number to 18000, that is still made of of small primes (2,3,5,7).

With this findNFFT method, nfft = 18432, which is

2^11 * 3 * 3

In this way, you process less samples, which saves on time. Any gain in speed by using a true radix-2 (32768) number is offset by the number of samples being processed, which is now much less. In one of my projects, this helped to cut the processing time by half.

Here’s the code for the findNFFT method – not the prettiest code but it does the trick.

/**
 * @brief Returns a vector containing the prime factors of n
 *
 * @param [in] The number to find the prime factors for
 * @return
 */
std::vector<int> primeFactors(int n) {
    std::vector<int> vec;

    while (n % 2 == 0) {
        vec.push_back(2);
        n /= 2;
    }

    for (int i = 3; i <= sqrt(n); i += 2) {
        while (n % i == 0) {
            vec.push_back(i);
            n /= i;
        }
    }

    if (n > 2)
        vec.push_back(n);

// std::cout << "Prime factors:" << std::endl;
// for (int j=0; j < vec.size(); j++)
// {
// printf("%d ", vec[j]);
// }
// printf("\n");
    return vec;
}

/**
 * @brief Used to find the appropriate fft integer for the input n
 * This uses the "formula" (N + D - 1)/D * D
 * Criteria: Output nfft should be a factor of 2,3,5
 *
 * @param [in] Integer to find nfft for
 */
int findNFFT(int n) {
    std::vector<int> ansPrimes;
    std::vector<int> firstPrimes;

    int d = 0;

    do {
        if (n > 2048) d = 512;
        else if (n > 1024) d = 256;
        else if (n > 128) d = 64;
        else if (n > 32) d = 32;
        else if (n > 8) d = 8;
        else d = 2;

        int fn = (n + d - 1) / d * d;
        firstPrimes = primeFactors(fn);

        for (int i = 0; i < firstPrimes.size(); i++) {
            if (firstPrimes[i] == 2 || firstPrimes[i] == 3 || firstPrimes[i] == 5) {
                ansPrimes.push_back(firstPrimes[i]);
                firstPrimes.erase(firstPrimes.begin() + i);
                i -= 1;
            }
        }

        int newN = 1;
        if (firstPrimes.size() > 0) {
            for (int i = 0; i < firstPrimes.size(); i++)
                newN *= firstPrimes[i];
        }

        n = newN;
        firstPrimes = {};

    } while (n != 1); // if n == 1 means that firstPrimes

    int ans = 1;
    for (int i = 0; i < ansPrimes.size(); i++)
        ans *= ansPrimes[i];

    return ans;
}

Texas Instruments C6678 Evaluation Kit – Booting Your Program from NAND/NOR

5280-cimg3088-_2d00_-small

If you’ve bought a evaluation kit for the Texas Instruments C6678 evaluation kit, and am wondering how to get your .out program binary to load on boot, and am confused by the manuals, here are a set of “golden path” instructions. (Actually, most of it is cut-and-pasted from various readme.txt files in different directories. It’s just placed here in proper order for normal people like me to understand.)

Procedure to Modify I2C Configuration

For some reason, the evaluation kit ships with the EEPROM’s nandBoot.bootFormat setting at ibl_BOOT_FORMAT_BBLOB. If we are using the .out file created with Code Composer, we need to change this is ibl_BOOT_FORMAT_ELF in order to boot the binary.

You likely only need to do this once to change the I2C configuration. Fortunately, TI has a helper program that makes use of the file i2cConfig.gel to change the I2C program.

- Modify the i2cConfig.gel file to your needs. It is located at C:\ti\mcsdk_2_01_02_05\tools\boot_loader\ibl\src\util\i2cConfig\i2cConfig.gel
 - Look for: setConfig_c6678_main() , this is the function you will calll later to set the i2c config
 - Look for: ibl.bootModes[1].u.nandBoot.bootFormat : If this is ibl_BOOT_FORMAT_BBLOB, change to ibl_BOOT_FORMAT_ELF;

- Load NO BOOT as usual , Launch Selected Configuration
 Set the dip switches (pin1, pin2, pin3, pin4) to:
 SW3(off, on, on, on),
 SW4(on, on, on, on),
 SW5(on, on, on, on),
 SW6(on, on, on, on)
 - Connect Target on Core 0
 - Load C:\ti\mcsdk_2_01_02_05\tools\boot_loader\ibl\src\make\bin\i2cparam_0x51_c6678_le_0x500.out program
 - Gel Files -> Load Gel File C:\ti\mcsdk_2_01_02_05\tools\boot_loader\ibl\src\util\i2cConfig\i2cConfig.gel
 - Scripts -> evm C6678 IBL -> setConfig_c6678_main()
 - Done

Procedure to Load NOR

NOR Writer Utility

NOR Writer is a simple utility to program a CCS format image/data file to the NOR flash.

Steps to program the NOR:

1. Be sure to set the boot mode dip switch to no boot/EMIF16 boot mode on the EVM.

2. Copy the binary file to writer\nor\evmc66xxl\bin directory, and rename it to app.bin.

3. Change the file_name and start_addr in writer\nor\evmc66xxl\bin\norwriter_input.txt if necessary.
 By default the NOR writer will load app.bin to DSP memory and write the data to NOR device start byte address 0,
 the start_addr should always be set to the start byte addess of a sector.

4. Open CCSv5 and launch the evmc66xx emulator target configuration and connect to core 0.

5. Load the program writer\nor\evmc66xxl\bin\norwriter_evm66xxl.out to CCS, be sure evmc66xxl.gel is used in CCS
 and DDR is intialized.

6. Open the Memory view (in CCSv5, view->Memory Browser), and view the memory address 0x80000000.

7. Load app.bin to 0x80000000:
 * In CCSv5, right click mouse in memory window, select "load memory".
 * Browse and select writer\nor\evmc66xxl\bin\app.bin (raw data format), click "next"
 * Set the Start Address to "0x80000000", Type-size to 32-bits, leave swap unchecked, click "finish"
 8. After the binary file is loaded into the memory, run the program (in CCSv5, press F8), it will start to program the
 NOR.

9. When programming is completed, the console will print "NOR programming completed successfully", if there
 is any error, the console will show the error message.

NOR Boot:
 Set the dip switches (pin1, pin2, pin3, pin4) to:
 SW3(off, off, on, off),
 SW4(on, on, on, on),
 SW5(on, on, on, off),
 SW6(on, on, on, on)
 This will set the boot param index to 0 to boot the NOR image, by default
 the boot configuration table sets the NOR offset address to be 0 and
 image format to be ELF for image 0.

 Procedure to Load NAND

– Programming the application on NAND or NOR flash
NOTE: This step is not needed if the application is booted from Ethernet.
(a) Use the NAND or NOR writer c6678 EVM from the tools directory.
(a) Flash the Application to NAND or NOR. For instructions please follow
the instructions given along with the NAND/NOR writer.

For all the I2C boot modes, user needs to set the boot dip switches to I2C master, bus address 0x51.
NAND Writer Utility

NAND Writer is a simple utility to program a CCS format image/data file to the NAND flash.

Steps to program the NAND:

1. Be sure to set the boot mode dip switch to no boot/EMIF16 boot mode on the EVM.

2. Copy the binary file to writer\nand\evmc66xxl\bin directory, and rename it to app.bin.

3. Change the file_name and start_addr in writer\nand\evmc66xxl\bin\nandwriter_input.txt if necessary.
 By default the NAND writer will load app.bin to DSP memory and write the data to NAND device start byte address 16384
 (start address of block 1). The start_addr should always be set to the start byte addess of a block.

4. Open CCSv5 and launch the evmc66xx emulator target configuration and connect to core 0.

5. Load the program writer\nand\evmc66xxl\bin\nandwriter_evm66xxl.out to CCS, be sure evmc66xxl.gel is used in CCS
 and DDR is intialized.

6. Open the Memory view (in CCSv5, view->Memory Browser), and view the memory address 0x80000000.

7. Load app.bin to 0x80000000:
 * In CCSv5, right click mouse in memory window, select "load memory".
 * Browse and select writer\nand\evmc66xxl\bin\app.bin (raw data format), click "next"
 * Set the Start Address to "0x80000000", Type-size to 32-bits, leave swap unchecked, click "finish"

8. After the data file is loaded into the memory, run the program (in CCSv5, press F8), it will start to program the
 NAND.

9. When programming is completed, the console will print "NAND programming completed successfully", if there
 is any error, the console will show the error message.

NAND Boot:
 Set the dip switches (pin1, pin2, pin3, pin4) to:
 SW3(off, off, on, off),
 SW4(on, off, on, on),
 SW5(on, on, on, off),
 SW6(on, on, on, on)
 This will set the boot param index to 2 to boot the NAND image, by default
 the boot configuration table sets the NAND offset address to be 16384
 (start of block 1).

Useful Stackoverflow Post for Rounding Numbers

http://stackoverflow.com/questions/1343890/rounding-number-to-2-decimal-places-in-c

Note Durations for Music Apps

I’ll just leave this here. Useful if you need to calculate the note values if you doing say, an arpeggiator.😉

Half note               =  120 / BPM
Quarter note            =   60 / BPM
Eighth note             =   30 / BPM
Sixteenth note          =   15 / BPM
Dotted-quarter note     =   90 / BPM
Dotted-eighth note      =   45 / BPM
Dotted-sixteenth note   = 22.5 / BPM
Triplet-quarter note    =   40 / BPM
Triplet-eighth note     =   20 / BPM
Triplet-sixteenth note  =   10 / BPM

Create a free website or blog at WordPress.com.

Up ↑