Core Audio output: Add sanity checking for supported formats, and support 64 bit float input data, in case anything actually uses that
parent
4dd46a1b5b
commit
ee05fe9e44
|
@ -300,6 +300,14 @@ static void convert_u32_to_s32(int32_t *buffer, size_t count)
|
|||
}
|
||||
}
|
||||
|
||||
static void convert_f64_to_f32(float *output, double *input, size_t count)
|
||||
{
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
output[i] = (float)(input[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -338,6 +346,25 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
|
|||
buffer += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case 8:
|
||||
for (i = 0; i < bytes; i += 8)
|
||||
{
|
||||
temp = buffer[7];
|
||||
buffer[7] = buffer[0];
|
||||
buffer[0] = temp;
|
||||
temp = buffer[6];
|
||||
buffer[6] = buffer[1];
|
||||
buffer[1] = temp;
|
||||
temp = buffer[5];
|
||||
buffer[5] = buffer[2];
|
||||
buffer[2] = temp;
|
||||
temp = buffer[4];
|
||||
buffer[4] = buffer[3];
|
||||
buffer[3] = temp;
|
||||
buffer += 8;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -442,6 +469,8 @@ tryagain:
|
|||
|
||||
size_t bytesReadFromInput = [self readData:inputBuffer + amountToSkip amount:(int)amountToWrite] + amountToSkip;
|
||||
|
||||
BOOL isFloat = !!(inputFormat.mFormatFlags & kAudioFormatFlagIsFloat);
|
||||
|
||||
if (bytesReadFromInput &&
|
||||
(inputFormat.mFormatFlags & kAudioFormatFlagIsBigEndian))
|
||||
{
|
||||
|
@ -449,12 +478,19 @@ tryagain:
|
|||
convert_be_to_le(inputBuffer, inputFormat.mBitsPerChannel, bytesReadFromInput);
|
||||
}
|
||||
|
||||
if (bytesReadFromInput &&
|
||||
!(inputFormat.mFormatFlags & kAudioFormatFlagIsFloat))
|
||||
if (bytesReadFromInput && isFloat && inputFormat.mBitsPerChannel == 64)
|
||||
{
|
||||
// Time for precision loss from weird inputs
|
||||
samplesRead = bytesReadFromInput / sizeof(double);
|
||||
convert_f64_to_f32(inputBuffer + bytesReadFromInput, inputBuffer, samplesRead);
|
||||
memmove(inputBuffer, inputBuffer + bytesReadFromInput, samplesRead * sizeof(float));
|
||||
bytesReadFromInput = samplesRead * sizeof(float);
|
||||
}
|
||||
|
||||
if (bytesReadFromInput && !isFloat)
|
||||
{
|
||||
size_t bitsPerSample = inputFormat.mBitsPerChannel;
|
||||
BOOL isUnsigned = !(inputFormat.mFormatFlags & kAudioFormatFlagIsSignedInteger);
|
||||
BOOL isFloat = NO;
|
||||
if (bitsPerSample <= 8) {
|
||||
samplesRead = bytesReadFromInput;
|
||||
if (isUnsigned)
|
||||
|
@ -679,6 +715,12 @@ static float db_to_scale(float db)
|
|||
inputFormat = inf;
|
||||
outputFormat = outf;
|
||||
|
||||
// These are the only sample formats we support translating
|
||||
BOOL isFloat = !!(inputFormat.mFormatFlags & kAudioFormatFlagIsFloat);
|
||||
if ((!isFloat && !(inputFormat.mBitsPerChannel >= 1 && inputFormat.mBitsPerChannel <= 32))
|
||||
|| (isFloat && !(inputFormat.mBitsPerChannel == 32 || inputFormat.mBitsPerChannel == 64)))
|
||||
return NO;
|
||||
|
||||
// These are really placeholders, as we're doing everything internally now
|
||||
|
||||
floatFormat = inputFormat;
|
||||
|
|
Loading…
Reference in New Issue