AUv3 AudioUnit Extension, IPCAUClient: bundle display name is nil - audiounit

In my AUv3 AudioUnit Extension I get this error message on the debug console output:
IPCAUClient.cpp:129:ConnectToRegistrationServer: IPCAUClient: bundle display name is nil
But there is a name in the info.plist file ... does anyone has the same problem?

This literally took me WEEKS to find the details to get this to work proper. There is NO sample code from Apple that would explain how this is supposed to work.
The main problem was to get the remote viewcontroller from the plug-in on the first start of the containing app. The AUv3 plug-in works perfect when it was inserted in Garageband once that would handle the registration to the system, but without this step there was no remote ViewController available.
I saw other implementations that read the AUv3 viewController from the bundle and connect the UI elements to the headless controller - this is boilerplate code and poor style IMO ... better use an AVAudioUnit and derive the AUAudioUnit_XH including the AUAudioUnitRemoteViewController from there by using this wrapper:
AU_AudioUnit = AVaudioUnit.AUAudioUnit
To get the AudioUnit to work inside the containing app there are several dependencies:
The AUv3 plug-in need to be registered using the registerSubclass method.
There needs to be an observer on AVAudioUnitComponentManagerRegistrationsChangedNotification installed.
The Inter-App Audio feature needs to be switched on in entitlements!
I hope this helps you out there and saves you lots of long and lonely nights ...

Related

How do I change the Unreal Engine AppleARKitLiveLink Settings via user input?

After compiling the Unreal Engine FaceARSample project the user can send the iPhone's facial blendshape data via the AppleARKitLiveLink plugin to a computer on their network with an IP address they define. I want to change it so the user can edit other LiveLink settings as well. Most importantly, the Subject Name.
So I found in the FaceARSample where the LiveLink source is created, inside of AppleARKitFaceSupportlmpl.cpp. The console command "LiveLinkFaceAR SendTo= [IP Address] " is used to change where LiveLink is publishing to. Upon pressing a button in the compiled app this console command is triggered which uses the line of code below to send the data over the network:
RemoteLiveLinkPublisher = FAppleARKitLiveLinkSourceFactory::CreateLiveLinkRemotePublisher(RemoteIp);
I've tried to make my own AppleARKitLiveLinkSourceFactory through blueprints but I couldn't figure it out. I found that I could edit the default subject name in the AppleARKit Project Settings. Is it possible to give the user access to these project settings via blueprints?
I'm confused about where to start. I've taken a look at the Maya LiveLink plugin, read the Unreal Engine documentation,and studied C++ for about 4 weeks now but I'm still confused. Do I need to somehow create an Unreal Engine module and #include the AppleARKit plugin then derive my own class from the AppleARKitLiveLinkSourceFactory? Do I need to create my own AppleARKit plugin from scratch?
Here's the documentation I read:
https://docs.unrealengine.com/en-US/Engine/Animation/LiveLinkPlugin/LiveLinkPluginDevelopment/index.html
You need to create your own plugin or game code, there you need to include the AppleARKit module editing your Build.cs then you can use their exported classes.
By instance all settings you can see in the project settings are driven by static UObjects, you can access all them if they are expose using something like this:
class* myclass = GetMutableDefault<>();
In this case you want to look for UAppleARkitSettings, now that been said, looks like that variable is protected, so you will not be able to modify it at all. if you really want to modify it through custom nodes in blueprints, you have 2 options, if you have the source, just change it to public, second option is remove the plugin from your engine, and paste it in your per project plugin folder and edit it there.
that's the closest you can go, nevertheless I suggest you changing that from the settings, looking to the architecture I can't see a valid reason to change that via BP, but it is up to you
Cheers and hope that helps

How to access frames of RTCVideoRenderer ? (ios)

I try to access frames of RTCVideoRenderer without success, can you help me please ?
I noticed that there is a "didCaptureVideoFrame" method in RTCVideoCapturerDelegate, but not in RTCVideoViewDelegate.
I have never done objc, I added a method in RTCVideoViewDelegate to get frames (bellow "didChangeVideoSize"), but it do not get fired, I guess it do not work like that.
I am able to access frames from the remote using Android using the "onFrame" of VideoSink, I thought it would be that easy using ios.
PS: To add the method, I took the framework from the pod and put it in the project, because I noticed that when you modify a pod, changes do not apply.
Here is the line I added :
- (void)videoView:(id<RTCVideoRenderer>)videoView didRenderVideoFrame:(RTCVideoFrame *)frame;
I will now try to compile the library with the changes I want.
EDIT:
I am now compiling the library, I noticed the need to change several files to be able to access frames, it will not be done just by adding 10 lines.
Solved thanks to this : How to get frame data in AppRTC iOS app for video modifications?
I used this line instead (because names changed since) :
#property(atomic, strong) RTCVideoFrame* videoFrame;
I wanted a "onFrame" like VideoSink on Android, but it will be ok for now.

How to notify OSX for an external file change

I found a way to refresh the finder when a file is externally changed using:
[[NSWorkspace sharedWorkspace] noteFileSystemChanged: path];
But it looks like this does not notify the file system or any other apps about the change. What I'm trying to do is somehow broadcast a notification to every app using the file, or tell the OSX itself (and then the OSX to notify the apps) that it has changed.
I also tried using:
[[NSDistributedNotificationCenter defaultCenter] postNotificationName: NSWorkspaceDidPerformFileOperationNotification object: nil];
But it does not work (also this notification is deprecated). And I don't know if other apps actually use this kind of notification system (for example I think VS Code is using it).
If there is a solution in c++ will be better, but objective c++ is also okay.

MFC add Typelib or ActiveX for OPOS

So at work I have been working for a few months on a OPOS driver for a few different things. I didn't create the project, but I have taken it over and am the only one developing it. So today I got curious about the way that it was done and I think that it may have started off on the wrong foot. I had to do a little bit of digging to find out that it uses the OPOS drivers from a company called MCS (Monroe Consulting Services) I downloaded 1.13 and installed the MSI version. I fired up VS created a new mfc dll. I then went to add a class. This is where I am confused.
It doesn't matter if i choose Typelib or ActiveX it usually gives me the same list of interfaces that I can add/extend from(with one exception that comes to mind with MSR it has an events interface that I can extend) And they both make the same header file (in the case with msr it is COPOSMSR.h) but one extends CCmdTarget, and the other extends CWnd. This is my first question. Which should I choose? what is a typelib/ what is a ActiveX component and how do they differ from one another.
The one i've been working on extends CCmdTarget. For the life of me I can not figure out how the driver knows to use one of the files (USNMSRRFID) but that is where all the development went into. (I broke it up a bit so it wasn't just one huge file) But that file doesn't extend COPOSMSR..it extends CCmdTarget as well. The only time i see anything mention the USN file is in MSRRFID.idl (which confuses me even more) Any one have clarity for this?
Part of me thinks this could make a very big impact when it comes time to deploy. A few of the test apps that have been written that make use of this driver require a somewhat confusing setup process that involves registering different drivers, copying files into a specific folder, setting up the registry and so forth. I think that if i can get a grip on what this all means and how to make a nice application that extends one of these OPOS devices properly that I could save my self further grief in the future.
Any tips or pointers??? Sorry if it is a newb question..but i am new to C++. I started with Java then moved to C# so some of this stuff is WAY over my head....
Well so I've done TONS of digging, and it is like searching for dinosaurs. Not easy, and hard to find. I will end up writing a nice little how to on this, but for now I will put up my findings. Although I still don't have this 100% i know I am close.
Turns out the typelib and activeX things are not a big concern but come into play after you've gotten started. ActiveX is for Control objects, and Typelib is for the Service Object. The most important thing is to get started correctly. I found a article on some Chinese website that offers some OK tips after figuring out the translation errors. To start with you will want to make a C++ project with Automation. It can be ATL or MFC. My preference is MFC. In the UPOS 1.13 pdf (or newer) in Appendix A section 8 it describes the responsibilities of the Service object. It has the main methods you need to implement. There are 16 methods you have to add, and at least 4 methods that get/set the properties for your OPOS device.
So to get started you will need to open up the add class wizard (for MFC classes) and click Add MFC class. You wil want your base class to be CCmdTarget. Come up with a classy Class name (I chose PinpadSOCPP) Then in the automation radio buttons select Creatable by type ID. It should fill in your type id as [Project Name].[Class name] so mine was PinpadSO.PinpadSOCPP. hit finish. This makes a nice interface file that you can use Class view to add methods and so forth to it.
As for adding the methods there are 2 things to note about this, and one of them I haven't figured out 100% yet. The first is that you have to implement all the methods in that section with the correct parameters and return values. Most of them return LONG (32bit signed number). and the 2 most common parameters are LONG and BSTR. (there is the occasional pointers for when you have "out" parameters) This is the part that I think that I am currently failing as I don't know if I have them all implemented correctly and that is why I am getting error 104/305 (which from the Chinese article says that I am missing something from my methods) I'm not sure if it is case sensitive, and I'm not sure of the 7 properties that look to need to have get/set which ones need to be implemented because the MSR SO that i am working on from work doesn't use them all and that SO is working. The other is that after you implement the base OPOS methods you have to also implement the extra methods from your specific OPOS device. Since I am doing PINPad there are 6 additional methods I have to implement.
Now this is a lot of time consuming work because you have to open up class view, navigate to the name of your project class. Expand it and go to the Interface portion. My Project name is PinpadSO, and the file that I am implementing this in is PinpadSOCPP (which means the interface name is IPinpadSOCPP) right click on IPinpadSOCPP and click add > add method. This brings you to a 2 step process. You fill in your return value, name of your function, add in all your parameters. Hit next and fill out some help string info (if you want) and hit finish. Now after you do that 20+ times it gets old and slow...and if you are like me you type Computer instead of Compute and flip flop letters, or forget to hit add on all your parameters. A person could make a nice little program to edit the 3 files that get changed each time you add a method and that would speed it up considerably. If you make a mistake you will need to open up [project name].idl, [class name].h, and [class name].cpp those are the 3 files that get the methods added to it directly. I recommend not making a mistake.
so now that all that hard work is out of the way. Compile your program. If you want to save your self an extra step you could turn on Auto Register in the linker project settings (NOTE: if you do that you'll need to run Visual Studio as admin if you program in vista or higher) this would save you of having to open a command window (admin) navigate to your DLL and use the command regsvr32 on that DLL. Nice thing is that you don't have to do that over and over again, just the once will do. I have no hard facts that it works like that every time but the MSR SO that I am working on, I'll make changes to it, compile it, then open up my OPOS tester program and the changes have taken affect.
After that you need to make your registry additions. navigate to HKLM\software\OLEforRetail\ServiceOPOS
(NOTE if you have a x64 machine you'll do this twice. One there, and again at HKLM\software\Wow6432Node\OLEforRetail\ServiceOPOS )
You'll need to add a Key for whatever OPOS device you are working with. I am making a pinpad SO so I made a Key called PINPad (check your UPOS document to see what name you should give it) Lastly choose a name for your device. I chose the model type of the from the vendor as my device name (C100) and made a sub key in PINPad. The default REG_SZ value needs to be your registered SO Device TypeID. in my case it is PinpadSO.PinpadSOCPP
if you don't have a OPOS test program (which I just made my own as a console program) then you can use the Microsoft OPOS test app (I couldn't get it to work on my x64 machine...but maybe you'll have better luck with it) If you do decide to make your own OPOS test app make sure you compile it for x86 machines (even if you have x64) OPOS does not like x64 for some reason (probably the pointers length I'd assume)..at any rate. Once you got it all setup run your test app (for my case I am just running OPOSPinpadClass pin = new OPOSPinpadClass(); Console.WriteLine(pin.Open("C100")); and hope for 0 :)
I am currently getting 104 (E_NOSERVICE)..and like i said before i think it is because I don't have all my methods correct. If that turns out to be the case I'll edit this response, or I'll report back and say what it really was.
Anywho, i hope this helps anyone else who decides they want to make their own SO. Good luck
UPDATE
OPOS checks a couple of properties when you call the Open command. One of the properties that is a must to implement is the in the GetPropertyNumber, and it is PIDX_ServiceObjectVersion. You will need to set this number to return (1000000 * majorVersion) + (1000 * minorVersion) + revision since I am making a OPOS 1.13 compatible SO my returned ServiceObjectVersion is 1013000. You will also want to implement 3 properties in GetPropertyString:
PIDX_DeviceDescription
PIDX_DeviceName
PIDX_ServiceObjectDescription
For all other values you can return a empty string or 0 until you start hooking all those things up.
As a side note if you don't want to make it in C++ you don't have to. You can make it in any language that you can write a ActiveX object in (such as a COM visible .NET class library)

Generating PDF with Quick Reports behind a Delphi Web Server

I have a Delphi web server providing some web services*. One of them is supposed to generate and return a PDF report.
The PDF creation is done with a QReport that is then exported into a PDF file with the ExportToFilter procedure.
The routine works fine when called from within an application, but when called behind a TIdTCPServer, it hangs and never finishes. Debugging it, I got tho the hanging point:
(note: I'm home right now and I don't have the source code. I'll try to reproduce quickrpt.pas' source as accurrate as I can remember).
procedure TCustomReport.ExportToFilter(TQRDocumentFilter filter);
...
AProgress := TQRFormProgress.Create(Application); // Hangs on this line
AProgress.Owner := QReport;
if ShowProgress then AProgress.Show;
QReport.Client := AProgress;
...
Searching the web, I found in this page (1) the suggestion to set ShowProgress to False, and edit the code so that it does not create the progress form when ShowProgress is set to false (apparently, this is due to QReport not being threadsafe).
So, I edited the code, and now I have this:
procedure TCustomReport.ExportToFilter(TQRDocumentFilter filter);
...
if ShowProgress then
begin
AProgress := TQRFormProgress.Create(Application);
AProgress.Owner := QReport;
AProgress.Show;
QReport.Client := AProgress
end;
...
Now, the report comes out. But then the service gets to an Invalid Pointer Exception (which I can't trace). Following calls to the service complete successfully, but when I shut down the service** it starts whining again with Invalid Pointer Exceptions, then the "MyServer has commited an invalid action and must be closed" windows message, then again a couple of times more, then just the pointer exception, then comes to error 216 (which as far as I could find out, is related to Windows access permissions).
Thanks!
Update (jan 5): Thanks Scott W. for your answer. Indeed, after some research, I found another suggestion that only the main thread can access some components. So I set the QR code back to normal and called the main method from a Synchronize call inside a TThread (so that way the main thread would handle it). But I still get the same error.
You mention you were able to generate PDF as a service with QR 4. Maybe that's why it's not working for me, since I'm using QR 3. On the other hand, you don't mention if you're doing that behind a TIdTCPServer (which is my case, providing web services) or if you run it by itself (for instance, during a batch process).
Anybody knows whether my QR version might be the problem? Thanks!
* Running Delphi 7 and QuickReport 3 on a Windows XP SP2. The server is based on Indy.
** I have two versions of the server: a Windows application and a Windows Service. Both call the same inner logic, and the problem occurs with both versions.
Update (mar 8): After all, my problem was that my printing routine was in another dll, and the default memory management module is somewhat crappy. Setting the first uses of my .dpr to be ShareMem overrides the memory management module with Borland's implementation, and solved my problem.
uses
ShareMem, ...
(1): http://coding.derkeiler.com/Archive/Delphi/borland.public.delphi.thirdpartytools.general/2006-09/msg00013.html
I'm guessing that QReport.Client is used somewhere later in the code, and with your modified code no longer assigning it to AProgress, you end up with an error.
Are you sure that you have to modify the QuickReport source? I have used QuickReport in a Windows Service to generate a PDF file and then attach to email message and all worked fine without having to modify the QR source. I don't recall exactly which settings had to be made, but it was done with Delphi 6 and QR 4.06.