Sunday, December 30, 2012

How to find out the traffic of a website

I'll just place the link with a good explanation of it from eHow

Example:

I did this for a website of a friend: questionity.com, and the value in dnScoop was about $68k while Google (just for the fun of the comparison) was more than $2B... Actually, it varies and when I clicked again (for Questionity) it was now $34k... I guess it depends on the stats at the time...

TrafficEstimate gives me about 340k visits on the last 30 days.

Alexa ranks it as the 1700 site in Spain, by traffic.

Saturday, December 15, 2012

Useful Matlab commands

These are some of the commands that I have used in Matlab pretty often. I just put them here for me to have a quick reference. Don't expect any fancy things... :)

t=(0:1/44e3:99999*1/44e3);
osc=sin(2*pi*t*3.9917e+003)';
mixer_out=filter_out.*osc;
bsdelayed=[zeros(25640-13170,1) ;bs];
bsshift=circshift(bs,22800);

figure
subplot(2,1,2)
plot(x,’r’)
clf
hold on
close all  % Closes all figures

filterbuilder
Y=Filter(Hbp,x);

z=amdemod(rx,3.9917e+003,44e3);
fmdemod;
pmdemod;
b=upsample(b,4400); % Insert zeros in between
bs=conv(b,symbol);
abs(fft(rx));

READ WAV FILE
[filename, pathname]=uigetfile('*.wav')
[m d]=wavfinfo(strcat(pathname,filename))
rx = wavread(strcat(pathname,filename));

READ BINARY FILE
[filename, pathname]=uigetfile('.\*.*')  % Open the dialog box
filen=strcat(pathname,filename) % Builds the full file path
fileID = fopen(filen)  % Opens the file and assigns it an ID
A = fread(fileID, inf, 'int16');   % Reads the full file into an Array A, assuming they are 16b integers
plot(A)

% See more http://www.mathworks.com/company/newsletters/articles/Matrix-Indexing-in-MATLAB/matrix.html
v = [16 5 9 4 2 11 7 14];
v(3) % gives 9
v([1 5 6]) % Gives 16, 2, 11
v(3:7) % Gives 9 4 2 11 7

http://www.mathworks.com/support/2014a/matlab/8.3/demos/working-with-arrays-matlab-video.html

Sunday, November 25, 2012

Jo soc CalalaƱ :D

Today is an historic day of elections in Catalonia. It is not the famous independence referendum, but I feel it is the time to speak up. For each side. Independentist (secessionist) have taken advantage of the crisis to get a lot of supporters. To me, it is a classical example of opportunism while proposing the wrong solution to the problem, while real solutions are urgently needed.

My problem is not with the feelings of anybody. Everybody can feel from wherever and even change those feelings during life. I start having a problem when people thinks that it is better for Catalonia, from the economic point of view. That I don't buy (surely not short/medium term), and specially when the new government would be made of the same people that drove Catalonia to this situation in the first place. Yes, the rest of Spain wasted their money, but did you guys checked what we did with ours in Catalonia???

Still, this could simply be an economical discussion, which is fine. My real problem is that the secessionist voice involves, besides bending reality, a speech of superiority and look down on other people. This smells to stuff that I simply don't like.

Below couple of post I placed in La Vanguardia, a nationalist newspaper, probably the biggest newspaper in Catalonia:


Basically, I think the different governments in Spain and its regions have proven to suck at it, so, it may be an exaggeration, but Germans may do a better job at it... Or at least strong auditing from outside.


Well, maybe not imaginary, but you understand me ;)

Peace!

PS.: By the way, if you want to know what is all this about, probably one of the most accurate articles on the topic would be this one from The economist:
http://www.economist.com/news/briefing/21567085-stabilising-spains-finances-without-tearing-its-social-fabric-apart-being-made-harder

Sunday, November 18, 2012

Filter design: From Matlab to C code

Note 1:  For this, I am using not only Matlab but the Signal Processing Toolbox. Got to study the other tools that Matlab has to deal with filters...
Note 2: I should write something like this but with some free tool out there... Anyhow, for the moment just use Matlab, as I have it available in my company...

Quick reading, it looks like there are couple of methods:
  1. A=ellip(specs) --> H=dfilt.df1(A) where A are the numerator and denominator coeff. This is kind of going analog to then move to digital.
  2. D=fdesign.bandpass(specs) --> H=design(D, ellip)
H is the object describing the digital filter (not exactly the coefficients, see more below). We will look in detail and extend the method 2 following Getting started with discrete time filters (dfilt) or fdesign objects.
1/ First got to get the object describing the specification of the filter we want. So, we use fdesign. Just type  "fdesign.bandpass" for a very simple syntax, or go to fdesign for more info.
In our case, we want to create a bandpass filter around 2.5KHz. So, we will do:

>> D=fdesign.bandpass(2000,2200,2800,3000,40,1,40,44100)
And we get:
D =
               Response: 'Bandpass'                     
          Specification: 'Fst1,Fp1,Fp2,Fst2,Ast1,Ap,Ast2'
            Description: {7x1 cell}                     
    NormalizedFrequency: false                          
                     Fs: 44100                          
                 Fstop1: 2000                           
                 Fpass1: 2200                           
                 Fpass2: 2800                           
                 Fstop2: 3000                           
                 Astop1: 40                             
                  Apass: 1                              
                 Astop2: 40

2/ To get the real design, we use:
>> h=design(D,'ellip')
And get:
h =
         FilterStructure: 'Direct-Form II, Second-Order Sections'
              Arithmetic: 'double'                              
               sosMatrix: [4x6 double]                          
             ScaleValues: [5x1 double]                          
     OptimizeScaleValues: true                                  
        PersistentMemory: false
For help, type designmethods(h) to get a list of filters.

3/ At this moment, we may actually like a different structure. Notice it used the default one (direct form II)


but we may want the more standard one. I am going to use direct form I as it is easier for me to identify what output number below matches what coefficient (notice that I am learning while doing this), so, it'll be easier to program:

Note: notice the error on the - sign in the added of b(nb) path.

So, we do:
>> h1  = convert(h,'df1')

h1 =

     FilterStructure: 'Direct-Form I'
          Arithmetic: 'double'      
           Numerator: [1x9 double]  
         Denominator: [1x9 double]  
    PersistentMemory: false

To see what we get, we can do:
>> info(h1)
Discrete-Time IIR Filter (real)   
-------------------------------   
Filter Structure    : Direct-Form I
Numerator Length    : 9           
Denominator Length  : 9           
Stable              : Yes         
Linear Phase        : No

4/ At this point, if we want to see what we got, it is as simple as using the Filter Visualization Tool:
hfvt=fvtool(h1);


5/ To get the coefficients, use:
num = get(h1,'Numerator');
den = get(h1,'Denominator');

In our case:
num =     0.0099   -0.0729    0.2418   -0.4681    0.5789   -0.4681  0.2418   -0.0729    0.0099
den =     1.0000   -7.4222   24.5776  -47.3746   58.1077  -46.4331  23.6104   -6.9884    0.9229

Where numerator and denominator are (when a0=1, like in our case):


In this kind of structure

Notice that a0 in Matlab is den(1) as the index starts at 1. So, we create in Matlab a piece of code that will do this (equivalent to running y=filter(h1,rx)):

rx2=[zeros(length(num)-1,1);rx];
y=zeros(length(rx)+length(num)-1,1);
for R=length(num):length(rx2)
    data=0;
    for N=1:length(num)
        data=data+rx2(R-N+1)*num(N);
    end
    for D=1:(length(den)-1)
        data=data-y(R-D)*den(D+1);
    end
    y(R)=data/den(1);
end

Translating this into C is straightforward. Notice that the initialization is important. I.e., getting both, input and output past values equal to zero. We can do that adding those in front of our sequences/arrays, or, just make zero the first set of values on those arrays. Of course, this is just for test and assuming you don't care about that data being lost... Either way, you get the point :)
 
The plot on the left is the result using "filter" while the one on the right is the one from the "C" code.


Other useful information:

For an automatic way to do it: Forum describing how to do it
From Simulink to C
From Matlab to HDL
Real Time Workshop Embedded Coder

Matlab filter design
Designing Low Pass FIR filters
FDATool

To use your filter (DUH!): y=filter(num,den,x);
To see the impulse response of your filter use [h,t] = impz(num,den) and plot(t,h)
To check if it is stable: isstable(h) - Note: I didn't get it to work where I can check it with filter running in a given precision

Nice write up on filter theory: http://www.mikroe.com/chapters/view/73/chapter-3-iir-filters/
And another one...
And one more!

Saturday, November 10, 2012

On abortion

Note: I wrote this before the election. I finally never went to vote...

====


So, I am ready to vote. I feel I would vote Obama because some of the things that Romney said I can't just agree to (like military spending can't be reduced, his healthcare policies,...). There are likely more things that Romney said that I disagree to, than that Obama said. Yeah, maybe I should be looking at what I agree, not to what I disagree :). But in one particular topic that I can't just ignore, abortion, both actually agree that morally is wrong. So, the difference is in what they do about it (one would put laws against while the other wouldn't).
http://2012.candidate-comparison.org/?compare=Romney&vs=Obama&on=Abortion

Somehow then, I started researching the topic, read posts, arguments, etc.. pro and against abortion. Not a single topic on pro-choice made the cut (we could review them here but that's probably for a different post), and end-up on the page of Ron Paul (who I wouldn't necessary agree on other topics) but who I think expressed my arguments with the exact words I would use:
"In the 1960s when abortion was still illegal, I witnessed, as an OB/GYN resident, the abortion of a fetus that weighed approximately 2 pounds. It was placed in a bucket, crying and struggling to breathe, and the medical personnel pretended not to notice. Soon the crying stopped. This harrowing event forced me to think more seriously about this important issue. That same day in the OB suite, an early delivery occurred and the infant boy was only slightly larger than the one that was just aborted. But in this room everybody did everything conceivable to save this child's life. My conclusion that day was that we were overstepping the bounds of morality by picking and choosing who should live and who should die. There was no consistent moral basis to the value of life under these circumstances. Some people believe that being pro-choice is being on the side of freedom. I've never understood how killing a human being, albeit a small one in a special place, is portrayed as a precious right."

See http://www.issues2000.org/tx/Ron_Paul_Abortion.htm

I believe that one day we will see the 40M abortions performed in US since Roe V. Wade in 1970 (and of course, all others in the rest of the world), like we see today slavery or many other horrible things humans defended, allowed, promote, or simply choose to ignore. This is not a post against those women that performed an abortion, but against a society that didn't do everything they can (including helping and respecting those moms) to protect that baby. I can't vote somebody who wouldn't put a stop to it, so, I can only vote blank :(. And just to be less negative, my deepest respect and kudos to those single moms out there.

PS.: Just so we are clear, I would agree with the argument that prohibition is not the "magic" solution to it, and that many other policies that governments also implement to reduce the number of abortions are more effective, but we can't just say "it's ok".

Sunday, October 28, 2012

Real time audio in Qt

[In my previous post I went through the use of QAudioDevice, but didn't show real time generation of audio. This post will not offer a solution to this either. Discusses the topic and leaves it where I left it, in case I want to re-take it. It will be a bit of rambling, sorry, but still, if you are on this topic and have not found the answer anywhere else, may point you in the right direction. If you have found a good example of this, please add a comment... Thanks!

Note: ha, like if anybody was ever going to read this :) ]

We are trying to have an audio system that has almost no latency, i.e, that a user can't notice it. This is important, for instance, in the case of games, where a player would see an explosion and should listen it right at the same time. On our example before, we had an audio buffer of about 1.5s (131072 bytes --> 65k samples --> ~1.5s at 44100samples/s audio). That meant that whenever we add something to that buffer, we will hear it a while later... Not good.

A thought was to reduce the length of that buffer, but if we simply were doing that we were getting some weird noises, maybe due to buffer overrun (?). We found documentation where they did mention that the buffer could be 10ms, but again, it did not work when we tried straight forward.

Using simply the audio play/stop may be fast, but still, the buffer has whatever it has, so, the latency from whenever the audio data is generated to the time is played would not change.

We also have the question on how signals work... Say we have a signal to service the timer updating the audio and one to service the audio generation itself, like creating the audio for an explosion. How do we service both on the right order? Something tells me this is done automatically on some kind of even queue.

But actually I am thinking that there may be several events happening at the same time, like two explosions, one after another, but with the first being long enough that is not finished by the time the next one comes... How do we deal with it? Several audio channels? Or mix first the audio and then output? Probably the second.

As we are talking about games, here is a good summary of the base framework in Qt:
http://boards.openpandora.org/index.php?/topic/108-qt-4x-as-a-game-engine/
Wish I had more time to play. Look at the demos!

Some people talks about using SDL which their authors describe as:
"Simple DirectMedia Layer is a cross-platform multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D video framebuffer. It is used by MPEG playback software, emulators, and many popular games, including the award winning Linux port of "Civilization: Call To Power."
http://www.libsdl.org/
http://www.libsdl.org/intro.en/usingsound.htmlhttp://www.libsdl.org/projects/SDL_mixer/

On the same topic of real time audio, there is a good post here:
http://lists.trolltech.com/qt-interest/1997-10/thread00245-0.html

Scroll down all the way, to read it. Basically it is saying that
"The conclusion is that you need to decouple the audio task from Qts event processing at all. I`ve done this by creating two threads: one that reads audio data from a mp3 decoder and a second one that copies the data to /dev/dsp. Both threads simply block on read/write and communicate through a simple buffer queue.

Calls into Qt from concurrent threads seems to be a bad idea as Qt is not thread safe by itself. That is: no signal/slot communication from within the threads, no interactions with the framework at all ;-)"

====

On a separate topic, on our previous post, we left unanswered what push vs pull mode were:

http://stackoverflow.com/questions/3426868/play-audio-data-using-qiodevice-qt4-6-with-vc

Explains it pretty well, showing that we indeed were using push. Notice that we used the setNotifyInterval at 50ms (we checked this by reading it too). That, at 44100 samples/s would mean every 4410 bytes, but this number does not really show up anywhere. It is not, certainly the periodSize, which is larger than this. So, notify happens more often but we do not get to see it. We plot every write call, but emptyBytes is at least periodSize long, not 4410?!?

One important thing I left out is that we are assuming that all what we write is written, but that is not truth. If the buffer is full, it wouldn't. Nevertheless, I think it is working because we are checking a priori how many bytes are empty.

Cheers!

PS.: If I ever figure it out may want to go reply other folks with the same doubt, like http://qt-project.org/forums/viewthread/20391

Friday, October 26, 2012

Qt audio output

This post is about generating audio in Qt with raw data. If you want to send a wav file straight to speaker, you can get done that very easily and there are plenty of places where they explain that... It is basically all about QAudioOutput. There is a full example of this here:
http://doc.qt.digia.com/4.7-snapshot/multimedia-audiooutput.html

Nevertheless, the example tries to cover all the cases, which makes hard to sort through what you really need. The simpler example that I finally followed was this:
http://www.qtforum.org/article/36606/solved-qaudiooutput-truncated-sinusoid-sound.html
After chewing on this, I created a different example (see below). The code works, but I am not an expert at all, my interpretation may be wrong and I am short in time to use any kind of error handling, close memory properly, etc... so, take it with a grain of salt :). Comments are very welcome :). The other thing is that the code does not solve the "real time" aspect of things... For instance, an explosion going off in a game and listening to it right then. I'll have to work on this...

1. The object representing the physical device:

You will need an object for the audio device itself, representing the physical element on the machine. That is the QAudioOutput object. The information of that device will be under a QAudioDeviceInfo object. If you go with the default, you don't even need to see what that info is (QAudioDeviceInfo::defaultOutputDevice).

This object has an internal buffer, which size is set by setbuffersize. You got to give it a number and I found out that the bigger the better was working. I think that had to do with overrun (see below).

2. The object to interface/pass data to the physical object in #1

To pass the data to that device, you need to connect the physical object to a QIODevice object. You do that by using QIODevice = QAudioOutput->start();

3. Getting the data to that "interface" object

Once you connected your interface object to the physical one, all what you need is to keep feeding data to the QIODevice. You do so using "write" (QIODevice::write). Every time you write there, it just appends that data to whatever you had written before. QAudioOutput reads from that buffer automatically (we don't see it).

The key is then to keep feeding data. Don't let the buffer empty and don't put too much/overrun the buffer (remember the size you set with setbuffersize). That is explained here:
http://lists.qt.nokia.com/pipermail/qt-interest/2010-June/024858.html

Basically, we don't know when exactly the audio is going to play it (I guess when the CPU or DMA or whatever gets to it...), but we don't care, we just need to make sure that there is always data to be played and to not exceed the buffer depth. I guess that there are several strategies here, but one can ask the device object to give us a notification every certain time. No timer needed, just use audioOutput->setNotifyInterval(50); where the 50 means 50ms (lot's of people use that). So, every 50ms, a signal will be generated and then we just connect that to a slot, to check if more data is needed and feed it if so:
QObject::connect(QAudioOutput, SIGNAL(notify()), this, SLOT(writeMoreData()));

So, every 50ms there will be a call to writeMoreData. What you do in there is up to you, but basically that's where you do the QIODevice::write to fill the buffer up. Just remember that you need to keep feeding "coherent" audio, so, you'll have to keep track on where you are in the audio you are sending. For instance, if a tone, you need to make sure that every time you come back to the writeMoreData, you feel the natural continuation of where you left it before.

But how do you know how many bytes you have empty in the audio buffer? Just use QAudioOutput::bytesFree.

There is one more thing... It is recommended that you write into the QIODevice in "chunks" of periodSize, which can be obtained with: QAudioOtuput::periodSize().

A final remark. Notice that your data may be, for instance, 16bits/sample (you set that when you create the QAudioOutput object, by passing a format), but a lot of the info returned by these functions is counted in bytes. So, take that into account...

Example

With that in mind, let's have a look to my code, which generates every second a tone of 4KHz during 100ms (no audio between tones).

My_Widget.h:
 /*  
  * My_Widget.h  
  *  
  * Created on: Oct 7, 2012  
  *   Author: a0214929 / Eduardo Bartolome  
  */  
 /*  
  * audioOutput is the physical object. It gets the data  
  * from the auIObuffer automatically, once they are connected.  
  * But we need to refill the auIObuffer from outside.  
  * In this case, as we may have async audio pieces (created  
  * from the game event, like key presses, explosions...)  
  * we have a big circular buffer (aubuffer) that stores  
  * those as they get in, and it's read out by the auIObuffer  
  * when a notify comes.  
  *  
  * The aubuffer is an array of 44100 2 byte elements *  
  */  
 #ifndef MY_WIDGET_H_  
 #define MY_WIDGET_H_  
  #include <QtCore/QObject>  
  #include <QtGui>  
  #include <QObject>  
  #include <QIODevice>  
  #include <QAudioOutput>  
 const float DurationSeconds = 0.1;  
 const int ToneFrequencyHz = 4000;  
 const int DataFrequencyHz = 44100;  
 const int BufferSize   = 44100; // Size of aubuffer, 1s long  
 class My_Widget:public QWidget  
 {  
      Q_OBJECT  
 public:  
      My_Widget( QWidget * parent = 0,Qt::WindowFlags f = 0):QWidget(parent,f)  
      {  
           initializeWindow();  
           initializeAudio();  
           writeMoreData();  
      }  
      ~My_Widget()  
      {  
           delete audioOutput;  
      }  
 public slots:  
      void writeMoreData();  
 private:  
      void initializeWindow();      // This creates the GUI  
   void initializeAudio();  
      // For the GUI  
      QTextEdit string_display;  
      QPushButton quitButton;  
      QGridLayout layout;  
      // For the audio  
      QAudioDeviceInfo deviceinfo;     // The information on the audio device  
      QAudioOutput*  audioOutput;      // Object that takes the data from the IO device  
                                              // when needed and sends to audio device.  
      QAudioFormat   format;  
      QIODevice*            auIObuffer;     // IODevice to connect to m_AudioOutput  
      signed short   aubuffer[BufferSize];     // Audio circular buffer  
      int                      readpointer;           // Pointer to the portion of the audio buffer  
                                                   // to be read.  
      int                      writepointer;           // Pointer to the portion of the audio buffer  
                                                // to be written.  
 };  
 #endif /* MY_WIDGET_H_ */  

My_Widget.cpp:
 /*  
  * My_Widget.cpp  
  *  
  * Created on: Oct 7, 2012  
  *   Author: a0214929  
  */  
 #include "My_Widget.h"  
 #include <qmath.h>  
 #include <qEndian.h>  
 void My_Widget::initializeWindow()  
      {  
        string_display.setReadOnly(true); // Displays all what user typed  
           string_display.setAcceptRichText(true);  
           quitButton.setText("Close");  
           // The order of creation sets the order of focus with tab  
           layout.addWidget(&string_display,0,0);  
           layout.addWidget(&quitButton,1,0,1,2);  
           this->setLayout(&layout);  
           this->setFocus(); // This has to be after creation.  
                                // AND without this, the tab and space  
                    // keys will just move focus within the widget  
           QObject::connect(&quitButton, SIGNAL(clicked()), qApp, SLOT(quit()));  
      }  
 void My_Widget::initializeAudio()  
 {  
   deviceinfo=QAudioDeviceInfo::defaultOutputDevice(); // Device info = default  
   audioOutput=0;  
   // qthelp://com.trolltech.qt.482/qdoc/qaudioformat.html  
   format.setFrequency(DataFrequencyHz);  
   format.setChannels(1);          // The number of audio channels (typically one for mono  
                                            // or two for stereo)  
   format.setSampleSize(16);      // How much data is stored in each sample (per channel)  
                                             // (typically 8 or 16 bits)  
   format.setCodec("audio/pcm");  
   format.setByteOrder(QAudioFormat::LittleEndian);  
   format.setSampleType(QAudioFormat::SignedInt);  
   // Constructor of QAudioDeviceInfo that gets the one from the default device  
   QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());  
   if (!info.isFormatSupported(format)) {  
     qWarning() << "Default format not supported - trying to use nearest";  
     format = info.nearestFormat(format);  
   }  
   audioOutput = new QAudioOutput(deviceinfo, format, this);  
      audioOutput->setNotifyInterval(50);  
      audioOutput->setBufferSize(131072); //in bytes  
   QObject::connect(audioOutput, SIGNAL(notify()), this, SLOT(writeMoreData()));  
   //auIObuffer->open(QIODevice::ReadOnly);  
      auIObuffer = audioOutput->start();  
   // We will delete this later, but for the moment we store a 0.1s tone on the aubuffer  
   // As the buffer is 1 second long, the buffer tone will be played periodically every 1s,  
   // after the buffer wraps around.  
   for (int sample=0; sample<BufferSize; sample++) {  
        signed short value=0;  
        if ((sample>20000) && (sample<20000+(DurationSeconds*DataFrequencyHz))){  
          float time = (float) sample/DataFrequencyHz ;  
          float x = qSin(2 * M_PI *ToneFrequencyHz* time);  
          value = static_cast<signed short>(x * 32767);  
        }  
        aubuffer[sample] = value;  
   }  
   string_display.insertPlainText(QString::number(aubuffer[1]));  
   string_display.insertPlainText(" ");  
   string_display.insertPlainText(QString::number(aubuffer[20000]));  
   string_display.insertPlainText(" ");  
   string_display.insertPlainText(QString::number(aubuffer[20001]));  
   string_display.insertPlainText(" ");  
   string_display.insertPlainText(QString::number(aubuffer[24409]));  
   string_display.insertPlainText(" ");  
   string_display.insertPlainText(QString::number(aubuffer[40000]));  
   string_display.insertPlainText(" ");  
   writepointer=0;  
   readpointer=0;  
 }  
 // When the audio calls for this routine, we are not sure how much do we need to write in.  
 // We need to make sure that what we send is n-sync with what is in the buffer already...  
 void My_Widget::writeMoreData()  
 {  
      int emptyBytes = audioOutput->bytesFree(); // Check how many empty bytes are in the device buffer  
      int periodSize = audioOutput->periodSize(); // Check the ideal chunk size, in bytes  
      string_display.insertPlainText(QString::number(emptyBytes));  
      string_display.insertPlainText(" ");  
      string_display.insertPlainText(QString::number(periodSize));  
      string_display.insertPlainText(" ");  
      int chunks = emptyBytes/periodSize;  
      while (chunks){  
           if (readpointer+periodSize/2<=BufferSize)  
           // The data we need does not wrap the buffer  
           {  
                auIObuffer->write((const char*) &aubuffer[readpointer], periodSize);  
                readpointer+=periodSize/2;  
                if (readpointer>BufferSize-1) readpointer=0;  
                string_display.insertPlainText("<");  
                }  
           else  
           // Part of the data is before and part after the buffer wrapping  
           {  
                signed short int_buffer[periodSize/2];  
                // We want to make a single write of periodSize but  
                // data is broken in two pieces...  
                for (int sample=0;sample<BufferSize-readpointer;sample++)  
                     int_buffer[sample]=aubuffer[readpointer+sample];  
                     for (int sample=0;sample<readpointer+periodSize/2-BufferSize;sample++)  
                          int_buffer[BufferSize-readpointer+sample]=aubuffer[sample];  
                          auIObuffer->write((const char*) &int_buffer, periodSize);  
                          readpointer+=periodSize/2-BufferSize;  
                          string_display.insertPlainText(">");  
                     }  
           string_display.insertPlainText(QString::number(chunks));  
           string_display.insertPlainText(" ");  
           --chunks;  
      }  
 }  

And the main.cpp:
 #include <QtGui>  
 #include "My_Widget.h"  
 int main(int argc, char *argv[])  
 {  
      QApplication a(argc, argv);  
      My_Widget window;  
   window.show();  
        return a.exec();  
 }  


This is what would be displayed in my case:


The first 5 numbers are the value in the circular buffer, just to make sure that things are what they need to be (blank, sine, blank).

"<" indicates that the chunk sent was before the end of buffer (wrap)
">" indicates that the chunk came part from before and part after the wrap.

The first number after < or > indicates the chunk number sent. Chunks are groups of periodSize long data. As we said, audio "likes" this.

The 2nd number shows the number of empty BYTES in the audio buffer when audio call the notification.

The 3rd number is telling us the periodsize, the number of BYTES. Do not confuse that with any kind of period in our buffer, ie., it is not the period of the sine we are sending or the wrapping period,
but just an internal number of the device audio buffer. We can see here is always constant at 26214.

So, now we can interpret the numbers. Initially (after the first five numbers) . One can see that we got 131070 BYTES free in the buffer. Notice that is almost what we set here: audioOutput->setBufferSize(131072);

As every audio sample is 2 bytes, that is 65535 audio samples long. We send a chunk of 26214 (13107 samples) from the beginning of our circular buffer (aubuffer, which is 44100 samples long), decrease counter to 4 and do that again. For 5 times.

Notice that as our circular buffer is 44100 long, we can do 3 reads of 13107 length before hitting the end of the buffer. I.e., 3 "<" hits and then one wrapping around the buffer, ie., ">". Then one more
from close to the beginning ("<") and the audio buffer will be full. Readpointer will be at 21435. (*)

Notice that in the first notification after that, the emptyBytes was zero (while period size was still 26214). But on the next notification (50ms) later, it seems to be the same as the periodSize. And it'll be like that from there on, with notifications coming fast enough that there is only one chunk per notification.

To continue with the analysis after where we left it at (*), one more read "<" and we are at 34532. Next one will hit the end of the buffer again, so, it'll be ">". And so on...

CHEERS!!!

PS1.: There is one more thing, called push vs pull mode, which refers, from the audio device perspective, how the data is obtained. I believe the above is "push" mode. Basically, we check how the buffer is doing and then write on it. The "checking" is triggered by the audio notify, but that is just like a timer, which I think is what the official Qt example shows (QTimer). Anyhow, I'll try to make a post on this as there is still some stuff I don't fully understand.

PS2.: By the way, to insert the code in blogger, I used the instructions here:
http://codeformatter.blogspot.com/

Also, I found this, but I didn't use it:
http://www.craftyfella.com/2010/01/syntax-highlighting-with-blogger-engine.html

Monday, October 8, 2012

Copying Qt project in Eclipse

Say you have a project in Qt that you want to use as starting point for a new project. Say that your environment is Eclipse. The fastest way I found to do this is:
  1. Create a new qt project: File->New->Project->Qt Console Project
  2. Go through the menus of the Wizard. Don't worry about it too much as we are going to delete it anyhow.
  3. Click Ok.
  4. The directory appears in the Workspace.
  5. Open it and delete the sources in there (.c, .h, .cpp...).
  6. Copy over the ones from your old project. 
  7. Fix the .pro so that it includes what needs to include. OR copy the old one over... They both should have the same inside.
  8. Click build
  9. It may ask you for the Launch Debug Configuration Selection, so, you pick MinGW gdb.
It should just work. You should be able to execute afterwards...

Saturday, September 29, 2012

HIDs

My low beam HID (xenon light) died on my GTI :(, so, I read about it and found some nice articles:

1. Very detailed on fabrication and differences between real and counterfeit:
http://priuschat.com/threads/not-all-hid-bulbs-are-created-equal.101472/

2. Explains how to replace them in the GTI:
http://golfmkv.com/forums/showthread.php?t=14545&highlight=HID+Headlight
http://www.golfmkv.com/forums/showthread.php?t=158496

The key to success is to place the bulb first on the lamp. Do not try with the holder. No way you can align everything. First practice with the broken bulb. The bulb has the return wire, which goes on bottom (see groove in the lamp) and two notches, a square one (on top) and a round one (to the side). If you place the bulb in the lamp correctly, it'll stay there as long as you don't touch it/shake it. Then, carefully, you bring the plastic holder, with the contact in the bottom, a bit offset to the side. Notice that the holder has two grooves internally, at 180 degrees of each other. These match with the two pivots from the bulb. So, if everything is aligned, the holder will go in, all the way to the lamp, matching grooves with pivots and then you rotate it like 10 degrees and will do "click". Again, practice all this with the old bulb. It is easy and no strength required. The main trouble is the narrow spots to work with. Basically I couldn't avoid my bulb to touch the sides of the lamp as I was placing it, but seems ok...

3. Some people will recommend taking the headlight out:

http://www.youtube.com/watch?v=1ryUllFJoVg

4. On fake HID (HID-like) lights:
http://reviews.ebay.com/quot-Xenon-quot-and-quot-HID-quot-and-quot-Plasma-quot-bulbs-the-truth?ugid=10000000001832221


My car uses D2S. In Autozone I can get Sylvania (PN39223) for $100, 3200 lumens, 4k (temp/color).
but in xenondepot.com I can get a Philips (original OEM) for $70!! So, it's a no brainer:
http://www.kbcarstuff.com/Philips-4300k-D2S-Bulb-p/pb-d2s-4k.htm
Update (2/9/20): The link above is dead. So bought them from Amazon for $45 (nice, they've gone down...). Also I had forgotten to write down the reference of the Philips, so, just pulled my just burnt bulb (driver side) and it says: Philips Germany, D2S, 35W, 85122, E1, 03V, DOT 323A04

I didn't give a try to the ebay types, but may have worked out (not sure).

UPDATE (6/16/2013): My driver side (the other side from the above fix) died today... Just for the record...

UPDATE (2/05/2020): My driver side suddenly changed color to purplish. Still lights up but I am thinking that it may die anytime... We will see...

PS.: By the way, turning off the DRL (day running lights) seems to be only possible through Wagcom. Stupid :(

PS2.: More stupid even. Because DRLs are always on, the inner headlights are useless. Very nice write up here: http://www.golfmkv.com/forums/showthread.php?t=66060

Saturday, August 25, 2012

Installing Matlab (exclusive for my company)

This works with my company, so, may not work with yours...
  1. Go to: http://flames.design.**.com/ReleaseMessages/mathworks/relmsg_mathworks_R2011b.html, where ** should be replaced by the name of my company.
  2. Follow those instructions.
  3. To add a toolbox follow also those instructions. It is missing that you will have to re-run the installer again if you did it at a different time. Going through control panel does not work:
  4. You have to do like if you were going to install a brand new matlab but choose "custom". 
  5. If the zip files of the toolboxes are on the same directory as the installer, it will detect those and list them here. 
  6. Select them and install... 
  7. It may give you an error that the installation may not be all right, in the end, but ignore it.
  8. Run Matlab and you should see those packages after typing "ver"
  9. You should be able to run also now the functions on those toolboxes.
  10. To change where you want it to start by default use, for instance: userpath('C:\MATLAB\work')
Enjoy! :)

Tuesday, August 21, 2012

Install CCS on Eclipse

------ Update -------

[See at the end of this update for my previous post]

So, everything look like it was working, but I did get some kind of java weird error. Maybe I should have installed 3.7.2 but anyhow, didn't get it to work so, got tired of this and installed CCS with its own Eclipse. I looked then at what that distribution had and it looks like it is more complete than the one that you just get by getting Eclipse and CDT.

The CCS on its own is:



The Eclipse+CDT+CCS is:


The extra packages are Target Management, Mylyn, EGit and one more (can't remember). I didn't see any difference between installing Eclipse SDK (170MB) or Eclipse Binary distribution (52MB). The first icon on the left comes from CDT, the 4th from Eclipse and the rest from CCS. I wonder if installing a different version of Eclipse would have changed this, but got sick of all these tests and now I am running Qt in Eclipse Juno, and CCS with its own distribution of Eclipse 3.8, apart.

--------------------------

This is the "supposed" way to make it work. Did it but didn't work:
http://processors.wiki.ti.com/index.php/Installing_CCS_over_Eclipse

Below there is a bunch of links with the same problem, but finally found the answer here:
http://e2e.ti.com/support/development_tools/code_composer_studio/f/81/p/207977/736711.aspx#736711

Basic solution, is an issue with Eclipse and CDT versions. So, get them here:
1. Download Eclipse Platform 3.8 (platform runtime binary) and unzip in, say, c:\Eclipse:
http://download.eclipse.org/eclipse/downloads/drops/R-3.8-201206081200/
http://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops/R-3.8-201206081200/eclipse-platform-3.8-win32.zip

2. Download CDT 8.1 here. Then use help-->install new software and point to the zip file:
http://www.eclipse.org/cdt/downloads.php
http://www.eclipse.org/downloads/download.php?file=/tools/cdt/releases/juno/r/cdt-master-8.1.0.zip

After that follow the instructions of the original link:
http://processors.wiki.ti.com/index.php/Installing_CCS_over_Eclipse

Once working, run Eclipse and you should get a splash screen with the license selection. You are ready to go!

======== Other links that didn't take me to the answer, just for future reference ============

A support inquiry telling them that they don't need to install Eclipse before CCS (CCS install already includes it):

http://e2e.ti.com/support/development_tools/code_composer_studio/f/81/t/191627.aspx
but what the heck, if you already had Eclipse...!

This guy has exactly the same problem/symptoms. Solves it by reinstalling stuff, but not exactly found out why:
http://e2e.ti.com/support/development_tools/code_composer_studio/f/81/t/177512.aspx

And yet one more guy:
http://e2e.ti.com/support/development_tools/code_composer_studio/f/81/t/164116.aspx
I add a post here...

By the way, the log error for CCS install is in program files x86 --> installhammer


Paste pictures in blogger

After having trouble with cut and paste kind of action, I found this link with useful hints:
http://tips.blogdoctor.me/2007/10/tips-on-pictures-in-blogger.html

Using QT with Eclipse - Hello world

I had found couple of articles on this, but they were not a fit and much more complicated than it really is (so, don't follow them if you are in my situation - Windows/Eclipse). The first looks like it was for Linux:
http://koehllab.genomecenter.ucdavis.edu/documentation/how-to/how-to-use-eclipse-with-qt/

The second was for the Qt Creator environment (full Qt SDK installation, not like me, with Eclipse):
http://qt-project.org/doc/qt-4.8/gettingstartedqt.html

Truth is that things are actually very straightforward. If you create a project following the Wizard, you'll get a Qt hello_world window without typing a line of code. The 2nd link is useful to understand how things are actually working (open the different pieces of code and compare them to see what the wizard did for you automatically). Also, trying to use a C++ project straight from Qt and add the libraries manually is probably a big pain, based on this post:
http://stackoverflow.com/questions/7775398/eclipse-qt-and-c-project-is-it-possible

Anyhow, so, how to do it? Basically, once Qt/Eclipse is installed (see my previous post on that) you should see on the top right of Eclipse a perspective for Qt:



Selecting the Qt C++ perspective and then File --> New we see:




If you don't press/select Qt C++, and you click in File --> New, you should at least see "Project..." option:



 And clicking it, you should get the option to create a Qt project.

 Either way, you can then just pick Qt Gui Project and follow the steps:
  1. The project name can have spaces in there.
  2. On the next dialog, try either one (QWidget, QMainWindow, ...). 
  3. No need to select any additional Qt modules (Core and Gui are enough)
  4. Click finish
Then go to project --> build project

After that, simply click the run (green "play" arrow) and the following window will show up (see note 1):


I selected MinGW gdb, click ok and wait for the application window to show up. Should be immediate. In this case:



That should be it! If you want to quickly play around, check the Project Explorer View, on the left of Eclipse.



If you double click in qt_another_test.ui you can see the shape of the window of your application. Clicking in the Qt C++ Widget Box tap, besides the Project Explorer view, you can add buttons, slide bars, etc... Click on the .cpp, .pro or .h to see the code. Now you can begin to make sense of the explanations on the tutorial listed above...
http://qt-project.org/doc/qt-4.8/gettingstartedqt.html

Good luck!

(1) If a message box shows up saying: "The selection can not be launched or there are not recent launches" right click on the project and select "Clean Project"