-
Notifications
You must be signed in to change notification settings - Fork 2k
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
lib/util/flac.cpp: Add support for flac data where bits_per_sample != 16. #11848
Conversation
Partially; the driver needs to do a set_stereo() on the cassette device (currently there seem to be no drivers using this). And it also needs this small change:
That fixed channels for flacs but gave me some weird echoing results on wavs before; it could be that I tested it wrongly though. |
It also works with 8 bit flacs. For example, abcstack from the abc80_cass software list converted to flac. This never worked for me before. |
src/lib/util/flac.cpp
Outdated
if (m_uncompressed_swap) | ||
{ | ||
sample = FLAC__int32(((uint32_t(sample) >> 24) & 0x000000ff) | ((uint32_t(sample) >> 16) & 0x0000ff00) | ((uint32_t(sample) >> 8) & 0x00ff0000) | (uint32_t(sample) & 0xff000000)); | ||
} |
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.
You could use swapendian_int32
from osdcomn.h
src/lib/util/flac.cpp
Outdated
int16_t flac_decoder::convert_to_int16(const ::FLAC__Frame *frame, FLAC__int32 sample) | ||
{ |
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.
Is there a reason this isn’t const
qualified? It shouldn’t change decoder state.
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.
No, made it const.
src/lib/util/flac.cpp
Outdated
if (frame->header.bits_per_sample >= 16) | ||
return int16_t(uint32_t(sample >> (frame->header.bits_per_sample - 16))); | ||
else | ||
return int16_t(uint32_t(sample << (16 - frame->header.bits_per_sample))); |
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.
You should round towards even when reducing resolution, and you should splat right when increasing resolution.
src/lib/util/flac.cpp
Outdated
if (m_uncompressed_swap) | ||
{ | ||
sample = FLAC__int32(((uint32_t(sample) >> 24) & 0x000000ff) | ((uint32_t(sample) >> 16) & 0x0000ff00) | ((uint32_t(sample) >> 8) & 0x00ff0000) | (uint32_t(sample) & 0xff000000)); | ||
} | ||
if (frame->header.bits_per_sample >= 16) | ||
return int16_t(uint32_t(sample >> (frame->header.bits_per_sample - 16))); | ||
else | ||
return int16_t(uint32_t(sample << (16 - frame->header.bits_per_sample))); |
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.
This won’t work if the output format isn’t native Endianness. You’re converting to output format before trying to adjust resolution. Do this on paper and see what happens.
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.
Yes, I had the operations swapped.
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 trouble with this is it’s a massive pessimisation. Remember this is going to be run for tens of thousands of samples at the very least. The current code is written with pipeline performance in mind – shifts are pre-calculated before the loop so the actual format conversion in the loop doesn’t require any conditional code.
With this change, tests based on input and output formats are being done for every sample.
Please think about how you can restructure the code to lift as much conditional code out of the loop as possible, and to make the code in the loop work with conditional moves rather than requiring more expensive branches.
Also, that doesn’t round towards even – it rounds towards positive infinity.
I have moved most of the old conditional code outside the loop by using templating. |
No description provided.