The selection of the amplitude of the signal, consisting of rectangular pulses, at different frequencies
The following is what I believe to be an optimized approach for performance in the presence of additive white noise when no other information is known about quantity of pulses or their amplitude distributions, beyond that they are 100 or 200 us long rectangular pulses and repeat at the 1KHz and 1.4KHz rates. This can be even further improved if any other further information is known (including learning from the data to see if anything else about the waveform is repetitive and therefore can be predicted once identified).

Note that the composite waveform consisting of the two pulse types combined  (pulse type meaning 1KHz and 1.4KHz pulses) repeats every 5 ms.

Create a mask to establish the timing of the pulse types. If the starting time between the two pulses is fixed and known then you can create a single reference waveform that is 0 everywhere except where a pulse could be located, and 1 in those positions using 100 us assumed durations. The longer the mask the better the result up to the maximum expected duration of a burst of pulses but keep it in 5 ms durations to take advantage of the cyclical property for using circular cross correlation.

If the 100 and 200 us pulses are equiprobable then in would actually be slightly better to use 200 us pulses in the mask (the break-even is when the ratio of 200 us pulses to 100 us pulses is $\sqrt{2}$, since 200 us masks would have 3 dB more noise which is offset by the signal increase if the mask allows the accumulation of $\sqrt{2}$ more pulses.)

Perform a circular cross correlation of the mask with a capture of the data. The result will have cyclical peaks showing the starting position of the 5ms composite pattern.

The circular cross correlation is given by the following which could be used as a quick test of the procedure:

$$XCORR = ifft(fft(b)conj(fft(a))$$

Where fft(a) is the fft of your mask and fft(b) is the fft of your data.

Here is a very simple example of that to demonstrate how this is done properly and the expected result since the OP is having trouble with this step:

&gt;&gt; mask = [1 0 0 0 0 1 0 0 0 0 1 0 0 0 0];
&gt;&gt; // create three cases of test data for example
&gt;&gt; dataAlligned = mask;
&gt;&gt; dataShiftOne = circshift(mask,1,2);
&gt;&gt; dataShiftTwo = circshift(mask,2,2);


Thus each would be:

mask = [1 0 0 0 0 1 0 0 0 0 1 0 0 0 0];

dataAlligned = [1 0 0 0 0 1 0 0 0 0 1 0 0 0 0];

dataShiftOne = [0 1 0 0 0 0 1 0 0 0 0 1 0 0 0];

dataShiftTwo = [0 0 1 0 0 0 0 1 0 0 0 0 1 0 0];

The circular cross correlation is done for each case above as:

&gt;&gt; corr = @(data,mask) ifft(fft(data).*conj(fft(mask)));


Below shows the result of this for each case:

&gt;&gt; corr(dataAllgined, mask)
ans = 
   3   0   0   0   0   3   0   0   0   0   3   0   0   0   0
&gt;&gt; corr(dataShiftOne, mask)
ans =
   0   3  -0   0   0   0   3  -0   0   0   0   3  -0   0   0
&gt;&gt; corr(dataShiftTwo, mask)
ans = 
   0   0   3   0  -0   0   0   3   0  -0   0   0   3   0  -0


Given the sparse nature of the mask, the implementation for the circular cross correlation would likely be more efficient in the time domain by repeated multiply and sums at all circular rotations of the mask. Given the mask only has values of 0 and 1 this would be quite simple to compute even in a microcontroller, as the multiply operation would just be a selection of which samples to sum. 

If the starting delay between the two pulse types is not known, then do the above with two masks; one for the 1KHz pulses and one for the 1.4KHz pulses.

Once timing is established for the above techniques, then we know when a pulse of each type should appear if a pulse is to be present in that interval. So at this point to detect each pulse use an integrate and dump that would integrate over 100us in two successive durations at all the expected start times. (This can be implemented with a moving average filter that has a width equal to the pulse duration, and taking the samples of the moving average output at each expected end of pulse location.)  A decision metric is established using a noise optimized threshold on the integrate and dump output to decide pulse present=1 or pulse not present = 0. The use of two successive durations is to determine if the pulse was 100us long or 200 is long (decoding 1,1 or 1,0 for that interval).

The magnitude of each pulse is the magnitude of the integrate and dump output scaled by the number of samples—- keep a running average of the detected magnitude for each pulse type and adjust the threshold based on the averaged magnitude to optimize the decision for pulse present or not present.