mirror of
https://codeberg.org/armin/pascalcompressor.git
synced 2026-10-11 16:51:56 +02:00
141 lines
No EOL
4.7 KiB
C
141 lines
No EOL
4.7 KiB
C
#include <AudioToolbox/AudioToolbox.h>
|
|
#include <dlfcn.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
static void check (OSStatus err, const char* what)
|
|
{
|
|
if (err != noErr)
|
|
printf ("FAIL: %s -> %d\n", what, (int) err);
|
|
else
|
|
printf ("PASS: %s\n", what);
|
|
}
|
|
|
|
int main (int argc, char** argv)
|
|
{
|
|
if (argc < 2)
|
|
{
|
|
printf ("usage: %s <Pascalcompressor executable path>\n", argv[0]);
|
|
return 2;
|
|
}
|
|
|
|
void* handle = dlopen (argv[1], RTLD_NOW | RTLD_LOCAL);
|
|
if (!handle)
|
|
{
|
|
printf ("FAIL: dlopen -> %s\n", dlerror());
|
|
return 1;
|
|
}
|
|
printf ("PASS: dlopen bundle\n");
|
|
|
|
AudioComponentDescription desc;
|
|
memset (&desc, 0, sizeof (desc));
|
|
desc.componentType = kAudioUnitType_Effect;
|
|
desc.componentSubType = 'Pscp';
|
|
desc.componentManufacturer = 'PscC';
|
|
desc.componentFlags = 0;
|
|
desc.componentFlagsMask = 0;
|
|
|
|
void* (*factory) (const AudioComponentDescription*) = dlsym (handle, "PascalcompressorAUFactory");
|
|
if (!factory)
|
|
{
|
|
printf ("FAIL: dlsym factory -> %s\n", dlerror());
|
|
return 1;
|
|
}
|
|
printf ("PASS: dlsym factory\n");
|
|
|
|
AudioComponent comp = AudioComponentRegister (&desc,
|
|
CFSTR ("Pascal: Pascalcompressor"),
|
|
0x00010000,
|
|
(AudioComponentFactoryFunction) factory);
|
|
if (!comp)
|
|
{
|
|
printf ("FAIL: AudioComponentRegister\n");
|
|
return 1;
|
|
}
|
|
printf ("PASS: AudioComponentRegister\n");
|
|
|
|
AudioUnit au = 0;
|
|
check (AudioComponentInstanceNew (comp, &au), "AudioComponentInstanceNew");
|
|
if (!au) return 1;
|
|
printf (" instance %p\n", (void*) au);
|
|
|
|
AudioUnitParameterInfo info;
|
|
memset (&info, 0, sizeof (info));
|
|
UInt32 infoSz = sizeof (info);
|
|
for (UInt32 pid = 0; pid < 7; ++pid)
|
|
{
|
|
if (AudioUnitGetProperty (au, kAudioUnitProperty_ParameterInfo,
|
|
kAudioUnitScope_Global, pid, &info, &infoSz) == noErr)
|
|
printf (" parameter %u: default %.3f name='%s'\n", (unsigned) pid,
|
|
(double) info.defaultValue,
|
|
info.cfNameString ? CFStringGetCStringPtr (info.cfNameString, kCFStringEncodingUTF8) : "?");
|
|
}
|
|
|
|
AudioStreamBasicDescription fmt;
|
|
memset (&fmt, 0, sizeof (fmt));
|
|
fmt.mSampleRate = 44100.0;
|
|
fmt.mFormatID = kAudioFormatLinearPCM;
|
|
fmt.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved;
|
|
fmt.mBytesPerPacket = 4;
|
|
fmt.mFramesPerPacket = 1;
|
|
fmt.mBytesPerFrame = 4;
|
|
fmt.mChannelsPerFrame = 2;
|
|
fmt.mBitsPerChannel = 32;
|
|
|
|
check (AudioUnitSetProperty (au, kAudioUnitProperty_StreamFormat,
|
|
kAudioUnitScope_Input, 0, &fmt, sizeof (fmt)),
|
|
"Set input format");
|
|
check (AudioUnitSetProperty (au, kAudioUnitProperty_StreamFormat,
|
|
kAudioUnitScope_Output, 0, &fmt, sizeof (fmt)),
|
|
"Set output format");
|
|
|
|
check (AudioUnitInitialize (au), "AudioUnitInitialize");
|
|
|
|
AudioUnitParameter p;
|
|
memset (&p, 0, sizeof (p));
|
|
p.mAudioUnit = au;
|
|
for (int i = 0; i < 7; ++i)
|
|
{
|
|
p.mParameterID = (AudioUnitParameterID) i;
|
|
p.mScope = kAudioUnitScope_Global;
|
|
p.mElement = 0;
|
|
AudioUnitParameterValue value = 0.0f;
|
|
OSStatus err = AudioUnitGetParameter (au, p.mParameterID, p.mScope, p.mElement, &value);
|
|
if (err == noErr)
|
|
printf (" parameter %d = %.3f\n", i, (double) value);
|
|
}
|
|
|
|
AudioUnitParameterValue setTo = 0.5f;
|
|
check (AudioUnitSetParameter (au, 1, kAudioUnitScope_Global, 0, setTo, 0),
|
|
"Set threshold parameter");
|
|
|
|
const int numFrames = 512;
|
|
AudioBufferList abl;
|
|
abl.mNumberBuffers = 2;
|
|
for (int c = 0; c < 2; ++c)
|
|
{
|
|
abl.mBuffers[c].mNumberChannels = 1;
|
|
abl.mBuffers[c].mDataByteSize = numFrames * sizeof (float);
|
|
abl.mBuffers[c].mData = malloc (abl.mBuffers[c].mDataByteSize);
|
|
memset (abl.mBuffers[c].mData, 0, abl.mBuffers[c].mDataByteSize);
|
|
}
|
|
|
|
AudioTimeStamp ts;
|
|
memset (&ts, 0, sizeof (ts));
|
|
ts.mSampleTime = 0.0;
|
|
ts.mFlags = kAudioTimeStampSampleTimeValid;
|
|
|
|
check (AudioUnitRender (au, NULL, &ts, 0, numFrames, &abl), "AudioUnitRender (silence)");
|
|
|
|
float* ch0 = (float*) abl.mBuffers[0].mData;
|
|
float peak = 0.0f;
|
|
for (int n = 0; n < numFrames; ++n)
|
|
peak = peak > ch0[n] ? peak : ch0[n];
|
|
printf (" rendered peak: %.6f\n", (double) peak);
|
|
|
|
for (int c = 0; c < 2; ++c) free (abl.mBuffers[c].mData);
|
|
|
|
check (AudioComponentInstanceDispose (au), "AudioComponentInstanceDispose");
|
|
dlclose (handle);
|
|
return 0;
|
|
} |