-
Notifications
You must be signed in to change notification settings - Fork 323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue #35 - implemented missing Int32_to_Int24_Dither function #798
base: master
Are you sure you want to change the base?
Issue #35 - implemented missing Int32_to_Int24_Dither function #798
Conversation
src/common/pa_converters.c
Outdated
{ | ||
/* REVIEW */ | ||
dither = PaUtil_Generate16BitTriangularDither(ditherGenerator); | ||
*dest = (signed char) ((((*src) >> 1) + dither) >> 7); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- review dither scaling
- assign to the three bytes of dest:
dest[0]
,dest[1]
,dest[2]
- will need separate big/little endian cases
what I would probably do is have a temporary 32 bit int to which I assign the scaled dithered result, and then have three statements that fan the scaled dithered result out to dest.
src/common/pa_converters.c
Outdated
*dest = (signed char) ((((*src) >> 1) + dither) >> 7); | ||
|
||
src += sourceStride; | ||
dest += destinationStride; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dest stride times 3
Regarding dither scaling, click the link and check the full doc comment for portaudio/src/common/pa_dither.h Line 73 in 68e963a
Note that when it says: "Ranged for adding to a 1 bit right-shifted 32 bit integer" that is for the case where the output is 16-bits. But you're working on 24-bit output so I think you need to scale the dither by 8 bits, that is
Let us know if that is consistent with your reading of the code and documentation in pa_dither.h/pa_dither.c and the other converter functions. Alternatively (and probably better) we could add new function |
@whyismynamerudy I'll keep helping out here, but I have marked this PR as a draft so that other people don't feel the need to review it. For the future, here are instructions for marking preliminary work in PRs as draft: |
@whyismynamerudy I would strongly recommend you use the program in
If you look closely, you will notice that the only converters that care about endianness are the converters that deal with 24-bit data. Other converters don't need to care about endianness because they can use the standard C types to represent the samples: Int16 (
The term "stride" in this context means step size: how many elements to skip on every iteration. This matters for interleaved audio (i.e. audio where the samples from all channels are interleaved, as in In this particular piece of code, the stride is expressed in samples. For non-interleaved audio, the stride is always 1. For interleaved mono audio, the converter will be called with a stride of 1; for interleaved stereo (2 channels), the stride is 2; for interleaved 5.1 (6 channels), the stride is 6; etc.
This again has to do with C number types and how C does pointer arithmetic, and again you will notice that only 24-bit converters do this kind of multiplication. In that particular code, the stride is expressed in samples. Converters that can get away with using standard C types (e.g. |
@RossBencina @dechamps Thank you both for you feedback on my code and answering my questions. I apologize for not being as active for the past 2 months - I had exams, but now that they are over I look forward to contributing to this project again. Currently, I'm looking through the dither generation functions to see how I would be able to implement As for the conversion functions, I am working on implementing the feedback I've gotten. For now (until the Again, thanks to both of you for the feedback - it's helping me learn quite a bit about coding and tackling issues I've never encountered before. |
…plementing PaUtil_Generate24BitTriangularDither
Pushed the changes I discussed in my previous comment. If the |
@whyismynamerudy check how dither is applied in this example: portaudio/src/common/pa_converters.c Line 1280 in f1733cc
You do not need to shift dither in your implementation. |
I looked through this and went back to my implementation and I see now - I agree that right shifting dither is unnecessary, I'll make the change and commit ASAP |
I think you need to remove |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for tackling this. Data type conversions, particularly ones involving packed 24-bit data, are very tricky.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for tackling this. Data type conversions, particularly ones involving packed 24-bit data, are very tricky.
…back on Int32_To_Int24_Dither
Thanks for the feedback! I've implemented the changes suggested by @philburk and removed If |
…itial implementation of Int32_To_UInt8_Dither
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've made some suggestions.
Have you run this on the test program?
|
||
PaInt32 *src = (PaInt32*)sourceBuffer; | ||
unsigned char *dest = (unsigned char*)destinationBuffer; | ||
PaInt32 *scaledDitherResult = (PaInt32*)destinationBuffer; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The most obvious red flag here is that you're casting a non-aligned ptr to a 32-bit aligned pointer. But also, why is the scaled dither result being stored in the destination buffer? In any case there's no reason to be storing a temporary result in the destination buffer.
PaInt32 *scaledDitherResult = (PaInt32*)destinationBuffer; |
while ( count-- ) | ||
{ | ||
/* REVIEW */ | ||
dither = PaUtil_Generate16BitTriangularDither(ditherGenerator); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dither = PaUtil_Generate16BitTriangularDither(ditherGenerator); | |
PaInt32 dither = PaUtil_Generate16BitTriangularDither(ditherGenerator); |
PaInt32 *src = (PaInt32*)sourceBuffer; | ||
unsigned char *dest = (unsigned char*)destinationBuffer; | ||
PaInt32 *scaledDitherResult = (PaInt32*)destinationBuffer; | ||
PaInt32 dither; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PaInt32 dither; |
{ | ||
/* REVIEW */ | ||
dither = PaUtil_Generate16BitTriangularDither(ditherGenerator); | ||
*scaledDitherResult = (PaInt32) ((((*src) >> 1) + dither) >> 7); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*scaledDitherResult = (PaInt32) ((((*src) >> 1) + dither) >> 7); | |
PaInt32 scaledDitherResult = (PaInt32) ((((*src) >> 1) + dither) >> 7); |
*scaledDitherResult = (PaInt32) ((((*src) >> 1) + dither) >> 7); | ||
|
||
#if defined(PA_LITTLE_ENDIAN) | ||
dest[0] = (unsigned char)(*scaledDitherResult); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove the *
now.
|
||
while( count-- ) | ||
{ | ||
/* IMPLEMENT ME */ | ||
/* REVIEW */ | ||
dither = PaUtil_Generate16BitTriangularDither( ditherGenerator ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
declare variable here as in previous function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good progress.
|
||
while( count-- ) | ||
{ | ||
/* IMPLEMENT ME */ | ||
/* REVIEW */ | ||
dither = PaUtil_Generate16BitTriangularDither( ditherGenerator ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dither could be declared here.
|
||
/* src += sourceStride; | ||
dest += destinationStride; */ | ||
*dest = (unsigned char)((((*src) >> 1) + dither) >> 23); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UInt8 audio is centered around 128 and ranges from 0 to 255.
So silence would be all 128s.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To clarify, you need to add an offset to convert Int32 to Uint8 format.
@whyismynamerudy - Good progress so far. Do you want to finish this up? |
Hi @philburk , sorry I was inactive for the past few months. I got busy with some other things over summer. I'm getting back to this and I hope to have provided an update over the next two weeks. |
Title. Implemented the missing function "Int32_To_Int24_Dither" in "pa_converters.c" using the specified coding guidelines.
I had a few questions: