ΣSigmaStudio Ask AI Русский Log in

Shift incoming I2S data left 7 bits

SigmaDSP & SigmaStudio Brewster Dec 4, 2025 00:00 10 replies Original on forum ↗
Thread Summary

Thread Summary

The user needs to shift I2S data left by 7 or 8 bits to align the sign bit and correctly sign-extend 16-bit 2's complement audio data for use with the ADAU1761's internal 5.23 format. The final solution involves a program using multiple cells to manipulate the data, as the ADAU1761 lacks built-in shift capabilities. The user provided a visual of the unaligned data and confirmed the issue with a portable oscilloscope.
AI Generated Content
Subscribe
Brewster Question
Dec 4, 2025 00:00

For reasons that are too long to explain here, the I2S data is arriving (logically) shifted right 7 bits. This is fine because it's really just 16 bits of valid data. Before I can use the data I need to shift it left 7 bits as that will get the sign bit back in the MSB and get the data back to the right values. It will be output via the on-chip DAC.

Looking through the ADAU1761 blocks I can't find any shifts. Guess that maybe makes sense with the 5.23 internal format. So instead I want to multiply by 128 as that would do the same thing if we treat the number as unsigned and if we were just talking a 24 bit integer. But it ends up again in 5.23 format so now need to sign extend somehow?

Do I need to multiply by 32 x 128 (i.e. 12 bits) to get the sign bit in the right place and then scale it back down to by 32 again to get the data in the right range for the DAC?

I'm going to start poking at it but figured I'm maybe not the first person to have a problem like this - but I couldn't find this question on the forum so for posterity here it is.

If anyone has ideas let me know.

Audio Signal Processors

software

i2s input

bit shift

SigmaDSP Audio Processors

adau1761

SS 4.7

Show More

DaveThib Reply
Dec 4, 2025 00:00

Hello Brewster,

There is a joke or "bit" of humor in here somewhere about you having an issue with you being a bit shifted but I guess I should not quit my day-job!

Can you give a little more clarification?

So you have 16 bit data coming into the part via I2S but the 16 bits is in the bottom, or last, 16 bits of the I2S 32 bit channel data slot?

So what is not clear is if the sign bit is extended or not? For instance, If it is a negative 16 bit number, bit 15 will be the sign bit and bit 0 the LSB. So is B15 only a "1" or are the rest of the bits above it, B31-B16 also a "1"?

I assume the answer is no, it is not, they are zeros so you need to get this into the core with the correct sign bit extended into the internal 5.23 format, correct?

I think I can see a way to do this. Give me a few hours to hack away at a possible solution or solutions for you.

I know you are used to the Sigma300/350 parts. In those parts there is some hardware built into the core to do logical or arithmetic shifts left or right which saves instructions. However, the 1761 is a Sigma200 core so it does not have this built in hardware feature.

You could multiply by 2 to shift left but when you get up to the actual sign bit it will not let you change it. I think I know how you could do that. So if you can clarify then I will spend some time on this.

Thanks,

Dave T

Brewster Reply
Dec 4, 2025 00:00

Hi Dave,

in terms of the 32 bit I2S word D[31:0] the data is in D[24:9] (if I did my math right?). Or pictorially from the perspective of the I2S port captures 24 bits:

0000 000X XXXX XXXX XXXX XXX0

where XX..XX is a 16 bit 2's complement (audio) data value.

I'm assuming that just gets shoved into the fractional .23 portion of the internal word, and normally the MSB of a 24 bit I2S input would get sign extended into the integer 5. portion of the internal word. So no multiply can get me out of this, I have to somehow force the sign extension. Need some sort of conditional logic but as you point out 1761 is kind of lacking compared to newer parts. But I feel like it should be possible.

BTW it might turn out what I need to do is 8 bit shift instead of seven. I've looked at the bits on the scope and I think I counted correctly, but it's so easy to be off by one that I figured better to try it and see which works.

The actual application (for now) is sending I2S over 700' of CAT7 wire - there's audio data in each direction so the sending is fine since it arrives synchronized with the clock. The return data is delayed 2x the cable delay (dang speed of light is just too slow, need to move to a different universe) in terms of when it's getting clocked in. Hence the screwy offset.

In the final system there will be a SERDES (in a FPGA) on each end and that will re-align the data, in the short term just have to show audio going bidirectionally so sending I2S was simple. If I can figure out the bit shift.

Thanks,

Brewster

DaveThib Reply
Dec 4, 2025 00:00

Hello Brewster,

Wait,... This is really strange.

So one channel of the I2S data is as you described below?

Brewster said:

0000 000X XXXX XXXX XXXX XXX0

So in the core you see the data like this correct?

00000.000 000X XXXX XXXX XXXX XXX0

5.23 number but the sign bit seven bits over to the right and obviously not sign extended.

So the sign bit is here:

0000 000X XXXX XXXX XXXX XXX0

OK, I will run with this and see what I can come up with.

Dave T

Brewster Reply
Dec 4, 2025 00:00

Hi Dave,

That's my assumption based on what I see come out of the DAC, I am multiplying the data by 8 twice to have a close to full scale signal. If I put a sine wave into the source I get what I think I should see for a number that's not been sign extended.

(yellow trace: using a small portable scope for the analog view so had to take a pix)

I didn't dump the values as I couldn't find anything in the blocks for the 1761 that looked like it would dump a block of data?

Brewster

pastedimage1764883232825v1.png
pastedimage1764883232825v1.png
DaveThib Reply
Dec 4, 2025 00:00

Hello Brewster,

Do this and see what it looks like coming into the core. If you can send a full scale sine wave it would be good but even a low level sign wave will go above and below zero so we will see all the bits changing.
Yes, you will have to click read a bunch of times to catch it at the right time. Perhaps a low frequency?

I have started to work on something but at the moment it is taking me some time to just setup the data input to be like you are describing so I can then setup a program to translate it.

Dave T

pastedimage1764884169025v1.png
pastedimage1764884169025v1.png
Brewster Reply
Dec 4, 2025 00:00

Here's what I get reading values (i thought there was a block to dump N values...add that to the suggestions pile)

I can't easily create waveforms either, the data is coming from an array of mics connected to an XMOS part. It actually decides pretty quickly that a pure tone must be noise and removes it. A swept sine gets through. (and there's A2B in the middle of all this too).

If you want to sketch out what you're thinking I'm happy to give it a shot here and see what I get (though have to head out the door soon). I was thinking some sort of bit test on the incoming sign bit, and that then selects one of two versions of the input where the math is done to get negative input value to be negative in 5.23 format. But that seemed awkward so figured if anyone could come up with the right way it was you :)

pastedimage1764885812926v1.png
pastedimage1764885812926v1.png
Brewster Reply
Dec 4, 2025 00:00

forgot to add that only one channel has data on it.

DaveThib Reply
Dec 4, 2025 00:00

Hello Brewster,

It is getting late and I have been hacking at this for a while. It is tricky and I also have to deal with the way SigmaStudio Readback cell does not give you a 00 in hex, instead it gives you a 0 for the eight bits! So 0,1,0,0 should really read 00,01,00,00. When you enter a hex number you have to use the double zeros of course. So it makes this bit manipulation that much more tricky.

So I have a program that I think works. I used a table of sample data that I think I have formatted to what you are getting as input.

So besides the table and table index pointer and my DC cell and readback for testing, you will think this is a lot of cells to do this. I would agree. It is not easy. There may be a more clever way to do this but my mind is a bit fried for today.

Here is the program so you can test it out.

Dave T

ADAU1761 Brewster Data Translating Program.dspproj

Brewster Reply
Dec 5, 2025 00:00

Hi Dave,

Thanks! That did the trick. I was trying to get to something that produced a one or zero for indicating <0 (as a 16 bit number) and then multiply the "sign extend" bits by that and then OR it vs. doing the mux approach that you used.

Though this was one of those times where I wish I could write a line of C code...

Anyway, problem solved, on to the next battle!

Thanks,

Brewster

DaveThib Reply
Dec 5, 2025 00:00

Hello Brewster,

Great! I was worried that I was out in left field and not exactly on target but hoped it would at least give you some ideas. There are always several ways to do things especially once you get to fairly low level hacking. I am glad you can use this for what you need.

Also, having to do this on the older Sigma200 cores really makes me appreciate the Sigma300/350 cores where this would have been much simpler!!

Yup! on to the next battle. We live to fight another day!

Take Care!

Dave T