Getting a codecs OSType from a UTType format in pyobjc - objective-c

I'm currently writing a script that processes batches of quicktimes, and its my first time using pyobjc (I have only written one other really simple script in actual objective-c). I need to be able to determine the four character OSType of the codec of the quicktimes so that I can properly use the same codec for images using addImage_forDuration_withAttributes_()
Because pyobjc only has access to the obj-c frameworks, I can't access any of the C functions from it. I am able to get the string format UTType of the codec:
from objc import YES, NO, nil
from Cocoa import *
from QTKit import *
movieAttribs = {
QTMovieOpenAsyncOKAttribute: NSNumber.numberWithBool_(NO),
QTMovieEditableAttribute: NSNumber.numberWithBool_(YES),
QTMovieFileNameAttribute: "quicktime.mov"
}
clip, err = QTMovie.movieWithAttributes_error_(movieAttribs, None)
track = clip.tracks()[0]
print track.format()
# u'Avid DNxHD Codec'
At this point I need to get the OSType, which for this codec would be 'AVdn'
I'm assuming I want something like this: https://developer.apple.com/library/mac/#documentation/MobileCoreServices/Reference/UTTypeRef/Reference/reference.html But I don't have access to it in pyobjc
My last resort is to shell out to qt_thing with something like this:
qt_thing --type=imco | grep "AVID DNxHD Codec" | awk -F: '{print $2}'
# Result: AVdn
But this is slower and I would rather do it all in code. I must be missing something that is available to me in the Cocoa/QTKit side of things. Anyone with any experience?
There is another SO question that again references using the C api to resolve the codec: Find out the Codec for a Quicktime Movie, but I can't obviously do that directly form pyobjc as far as I know.

While I waited for someone to answer, and kept digging, even into the Carbon module... I found that there are quite a number of methods wrapped into pyobjc objects that are not really documented in the docs or probably even present in the native QTKit objc. I figure this is to offset the lack of access to the Quicktime C-api layer.
First my search turned up this QTKit class: QTFormatDescription
But there was no clear way how to create one of these. Apparently I wasn't the only one confused as to how to retrive one
When I started searching the actual members of QTMovie, QTTrack, and QTMedia objects, looking for possibly a way to retrieve a QTFormatDescription object, I stumbled across a method call: QTTrack.mediaSubType
>>> movie = QTMovie.alloc().initWithFile_error_("/path/to/quicktime.mov", None)
>>> track = movie.tracks()[1]
>>> track.mediaSubType()
u'AVdn'
I guess they do wrap up a lot of convenience methods into the pyobjc instances so that you can retrieve this kind of information without the C-api. Its just a shame that its so undocumented.
For anyone looking for random functionality like this, all I can recommend is doing something like this to find any added non-arg methods that might be available to you:
>>> print '\n'.join([attrib for attrib in dir(QTTrack) if not '_' in attrib])
....
mediaName
mediaRetained
mediaSubType
mediaType
mediaTypeInMedia
...

pyobjc does contain access to UTType it's under LaunchServices.
from LaunchServices import *
UTCreateStringForOSType()
UTGetOSTypeFromString()

Related

What is the syntax and correct way of using SourceBaby, one of the bots used in the Perl 6 related channels?

SourceBaby is apparently one of the Whateverable bots, running in the #perl6 and other IRC channels, which is able to locate the source of Perl 6 functions. However, the syntax is kind of difficult to figure out. To locate lazy-if, which is a method of Any, you have to do (like in the link).
s: Any, "lazy-if", \(1)
I have been trying to google for instructions, but I just couldn't find them. It's not in the official list of Whateverable bots, either. Anyone can help?
It's not in the official list of Whateverable bots, either.
That's 'cause it's not a Whateverable bot. There are several other community bots that aren't Whateverables, including huggable and buggable bots.
Asking the bot for help gives you a hint where to look for:
<Zoffix> SourceBaby: help
<SourceBaby> Zoffix, Use s: trigger with args to give to sourcery
sub. e.g. s: Int, 'base'.
See http://modules.perl6.org/dist/CoreHackers::Sourcery
The CoreHackers::Sourcery module is just a thin wrapper around core functionality of Code object's .file and .line methods. They report the location of routine's definitions for all routines and for core routines they have this special SETTING:: string that shows the location in rakudo's source (or whatever compiler you're using):
say "{.file}:{.line}" with Any.^lookup: "lazy-if"
# SETTING::src/core/Any.pm6:472
And the bot is a thin wrapper around CoreHackers::Sourcery's sourcery routine. And that's all you do when triggering the bot. You're literally typing arbitrary Perl 6 code that will be inserted as args into that routine and then evaled.
The two calling forms are:
:(Callable:D \to-lookup, Capture \args?)
:(Mu \object, Str:D \method-name, Capture \args?)
The first one is a 1-2 arg form that you'd usually use with subroutines:
<Zoffix> s: &say
<SourceBaby> Zoffix, Sauce is at https://github.com/rakudo/rakudo/blob/d1d31fd57/src/core/io_operators.pm6#L10
And the second one is a 2-3 arg form that you'd usually use with methods on objects:
<Zoffix> s: $*ERR, 'print'
<SourceBaby> Zoffix, Sauce is at https://github.com/rakudo/rakudo/blob/d1d31fd57/src/core/IO/Handle.pm6#L604
The last arg in both forms is a Capture of arguments that you want to call the callable with. It's optional, in which case you'd get a proto's location for multi routines. So usually you'd specify the args to get a specific candidate's location:
<Zoffix> s: $*ERR, 'print', \(1, 2, 3)
<SourceBaby> Zoffix, Sauce is at https://github.com/rakudo/rakudo/blob/d1d31fd57/src/core/IO/Handle.pm6#L609

Using pyfftw properly for speed up over numpy

I am in the midst of trying to make the leap from Matlab to numpy, but I desperately need speed in my fft's. Now I know of pyfftw, but I don't know that I am using it properly. My approach is going something like
import numpy as np
import pyfftw
import timeit
pyfftw.interfaces.cache.enable()
def wrapper(func, *args):
def wrapped():
return func(*args)
return wrapped
def my_fft(v):
global a
global fft_object
a[:] = v
return fft_object()
def init_cond(X):
return my_fft(2.*np.cosh(X)**(-2))
def init_cond_py(X):
return np.fft.fft(2.*np.cosh(X)**(-2))
K = 2**16
Llx = 10.
KT = 2*K
dx = Llx/np.float64(K)
X = np.arange(-Llx,Llx,dx)
global a
global b
global fft_object
a = pyfftw.n_byte_align_empty(KT, 16, 'complex128')
b = pyfftw.n_byte_align_empty(KT, 16, 'complex128')
fft_object = pyfftw.FFTW(a,b)
wrapped = wrapper(init_cond, X)
print min(timeit.repeat(wrapped,repeat=100,number=1))
wrapped_two = wrapper(init_cond_py, X)
print min(timeit.repeat(wrapped_two,repeat=100,number=1))
I appreciate that there are builder functions and also standard interfaces to the scipy and numpy fft calls through pyfftw. These have all behaved very slowly though. By first creating an instance of the fft_object and then using it globally, I have been able to get speeds as fast or slightly faster than numpy's fft call.
That being said, I am working under the assumption that wisdom is implicitly being stored. Is that true? Do I need to make that explicit? If so, what is the best way to do that?
Also, I think timeit is completely opaque. Am I using it properly? Is it storing wisdom as I call repeat? Thanks in advance for any help you might be able to give.
In an interactive (ipython) session, I think the following is what you want to do (timeit is very nicely handled by ipython):
In [1]: import numpy as np
In [2]: import pyfftw
In [3]: K = 2**16
In [4]: Llx = 10.
In [5]: KT = 2*K
In [6]: dx = Llx/np.float64(K)
In [7]: X = np.arange(-Llx,Llx,dx)
In [8]: a = pyfftw.n_byte_align_empty(KT, 16, 'complex128')
In [9]: b = pyfftw.n_byte_align_empty(KT, 16, 'complex128')
In [10]: fft_object = pyfftw.FFTW(a,b)
In [11]: a[:] = 2.*np.cosh(X)**(-2)
In [12]: timeit np.fft.fft(a)
100 loops, best of 3: 4.96 ms per loop
In [13]: timeit fft_object(a)
100 loops, best of 3: 1.56 ms per loop
In [14]: np.allclose(fft_object(a), np.fft.fft(a))
Out[14]: True
Have you read the tutorial? What don't you understand?
I would recommend using the builders interface to construct the FFTW object. Have a play with the various settings, most importantly the number of threads.
The wisdom is not stored by default. You need to extract it yourself.
All your globals are unnecessary - the objects you want to change are mutable, so you can handle them just fine. fft_object always points to the same thing, so no problem with that not being a global. Ideally, you simply don't want that loop over ii. I suggest working out how to structure your arrays in order that you can do all your operations in a single call
Edit:
[edit edit: I wrote the following paragraph with only a cursory glance at your code, and clearly with it being a recursive update, vectorising is not an obvious approach without some serious cunning. I have a few comments on your implementation at the bottom though]
I suspect your problem is a more fundamental misunderstanding of how to best use a language like Python (or indeed Matlab) for numerical processing. The core tenet is vectorise as much as possible. By this, I mean roll up your python calls to be as few as possible. I can't see how to do that with your example unfortunately (though I've only thought about it for 2 mins). If that's still failing, think about cython - though make sure you really want to go down that route (i.e. you've exhausted the other options).
Regarding the globals: Don't do it that way. If you want to create an object with state, use a class (that is what they are for) or perhaps a closure in your case. The global is almost never what you want (I think I have one at least vaguely legit use for it in all my writing of python, and that's in the cache code in pyfftw). I suggest reading this nice SO question. Matlab is a crappy language - one of the many reasons for this is its crap scoping facilities which tend to lead to bad habits.
You only need global if you want to modify a reference globally. I suggest reading a bit more about the Python scoping rules and what variables really are in python.
FFTW objects carry with them all the arrays you need so you don't need to pass them around separately. Using the call interface carries almost no overhead (particularly if you disable the normalisation) either for setting or returning the values - if you're at that level of optimisation, I strongly suspect you've hit the limit (I'd caveat this that this may not quite be true for many many very small FFTs, but at this point you want to rethink your algorithm to vectorise the calls to FFTW). If you find a substantial overhead in updating the arrays every time (using the call interface), this is a bug and you should submit it as such (and I'd be pretty surprised).
Bottom line, don't worry about updating the arrays on every call. This is almost certainly not your bottleneck, though make sure you're aware of the normalisation and disable it if you wish (it might slow things down slightly compared to raw accessing of the update_arrays() and execute() methods).
Your code makes no use of the cache. The cache is only used when you're using the interfaces code, and reduces the Python overhead in creating new FFTW objects internally. Since you're handling the FFTW object yourself, there is no reason for a cache.
The builders code is a less constrained interface to get an FFTW object. I almost always use the builders now (it's much more convenient that creating a FFTW object from scratch). The cases in which you want to create an FFTW object directly are pretty rare and I'd be interested to know what they are.
Comments on the algorithm implementation:
I'm not familiar with the algorithm you're implementing. However, I have a few comments on how you've written it at the moment.
You're computing nl_eval(wp) on every loop, but as far as I can tell that's just the same as nl_eval(w) from the previous loop, so you don't need to compute it twice (but this comes with the caveat that it's pretty hard to see what's going on when you have globals everywhere, so I might be missing something).
Don't bother with the copies in my_fft or my_ifft. Simply do fft_object(u) (2.29 ms versus 1.67 ms on my machine for the forward case). The internal array update routine makes the copy unnecessary. Also, as you've written it, you're copying twice: c[:] means "copy into the array c", and the array you're copying into c is v.copy(), i.e. a copy of v (so two copies in total).
More sensible (and probably necessary) is copying the output into holding arrays (since that avoids clobbering interim results on calls to the FFTW object), though make sure your holding arrays are properly aligned. I'm sure you've noted this is important but it's rather more understandable to copy the output.
You can move all your scalings together. The 3 in the computation of wn can be be moved inside my_fft in nl_eval. You can also combine this with the normalisation constant from the ifft (and turn it off in pyfftw).
Take a look at numexpr for the basic array operations. It can offer quite a bit of speed-up over vanilla numpy.
Anyway take what you will from all that. No doubt I've missed something or said something incorrect, so please accept it with as much humility as I can offer. It's worth spending a little time working out how Python ticks compared to Matlab (in fact, just forget the latter).

top command in Mac OS X got truncated

I'm trying to use the "top" command in MacOS X to determine which app is using the resources.
When I do:
top -stats "pid,command"
the command column is truncated, if the process name is too long.
if you look at the activity monitor, the process name is shown properly (with full name) + icon. My questions are:
how to get the full process name?
sometimes the app icon show next to the process name, is there anyway to do the similar thing using objective-c? should I simply navigate to the app contents folder and grab the icns image?
First, if you're trying to get the data programmatically, driving top is almost definitely not what you want to do.
But, to answer your direct questions:
how to get the full process name?
There is no way to control the truncation of commands. You can use the -ncols parameter to set the width of the output for non-interactive output, but that doesn't stop top from truncating if it wants to.
sometimes the app icon show next to the process name, is there anyway to do the similar thing using objective-c? should I simply navigate to the app contents folder and grab the icns image?
No. How would you deal with apps that have multiple .icns files, e.g., for document icons? (Try it with iTunes, for example. If you pick the first .icns, you get the AIFF document icon; if you pick the last, you get the internal-use recent TV shows icon.)
The right way to do it is to get the NSBundle for the application, then do something like this:
NSString *iconFile = [bundle objectForInfoDictionaryKey:#"CFBundleIconFile"];
if (iconFile) {
NSString *iconPath = [bundle pathForResource:iconFile ofType:#"icns"];
// load and display the icon
}
So, how do you actually want to do this, if not by driving top?
Well, what you're asking for is actually not a well-defined thing. OS X has four different notions of task/process/program/application that don't correspond 1-to-1, and that makes life difficult if you want to write a mashup of two programs that use different notions—e.g., top deals in BSD processes, while Activity Monitor deals in OS X applications.
If what you actually want is the same list top uses, it's open source, so you can read it and do the same thing it does.
But the simplest way to get the list of BSD processes is probably the interfaces in libproc.h, in particular proc_listallpids and proc_pidinfo. For example:
int dump_proc_names() {
int buf[16384];
int count = proc_listallpids(&buf, 16384*sizeof(int));
for (int i = 0; i != count; ++i) {
int pid = buf[i];
char path[MAXPATHLEN+1] = {0};
int ret = proc_pidinfo(pid, PROC_PIDPATHINFO, 0,
&path, sizeof(path));
if (ret < 0) {
printf("%d: error %s (%d)\n", pid, strerror(errno), errno);
} else {
printf("%d: %s\n", pid, path);
}
}
}
Obviously in real code you're going to want to allocate the buffer dynamically, return the values instead of just dumping them, get more than just the paths, etc. But this is enough to give you the basic idea. (When you go to get additional information, be aware that you if you ask for any struct, you will get an EPERM error unless you have rights to see every member of that struct. So, don't go asking for PROC_PIDTASKALLINFO if you only want PROC_PIDT_SHORTBSDINFO.
Anyway, since this API deals with BSD processes (and Mach tasks), not applications, it won't directly help you get at the NSBundle you want to provide Activity Monitor-style features.
There is no way to do this that's entirely correct, but you can probably get away with something like this:
NSString *path = processPath;
while (path && ![path isEqualTo:#"/"]) {
NSBundle *bundle = [NSBundle bundleWithPath:path];
if (bundle) {
if ([bundle executablePath != processPath]) return nil;
return bundle;
}
path = [path stringByDeletingLastPathComponent];
}
There are probably alternative ways to do this, each with different tradeoffs. For example, using -[NSWorkspace runningApplications], storing the results in a dictionary mapping the bundle executable path to the bundle, and using that to look up each process is simple, but it only seems to be useful for applications owned by the current user (and probably in the current session). On the other hand, enumerating all bundles on the system, or asking Spotlight, or similar would probably be too slow to do on the fly, but would go out of date if you cached them on first run.
Another option, in place of libproc, is to use libtop.
Unfortunately, Apple doesn't provide it. They do have a libtop implementation, which they use for their top tool, but it's actually embedded in the source to top and not available from outside. You can find the source (at the link above) and embed it into your program the same way top itself does.
Alternatively, both GNU and BSD process utilities have Mac ports (although knowing which name to use with Homebrew/MacPorts/Google search isn't always easy…), so you could build one of those and use it.
However, unless you're trying to write cross-platform software (or already know how to write this code for linux or FreeBSD or whatever), I think that just adds extra complexity.

function that returns value from dlsym()?

Stupid question that I'm sure is some bit of syntax that's not right. How do I get dlsym to work with a function that returns a value? I'm getting the error 'invalid conversion of void* to LSError (*)()' in the following code - trying to get the compile the linux lightscribe sample program hoping that I can link it against the OSX dylib (why the hell won't HP release an actual Cocoa SDK? LS has only been around for what? 6 or 7 years now?):
void* LSHandle = dlopen("liblightscribe.1.dylib", RTLD_LOCAL|RTLD_LAZY);
if (LSHandle) {
LSError (*LS_DiscPrinter_ReleaseExclusiveUse)() = dlsym(LSHandle, "LS_DiscPrinter_ReleaseExclusiveUse");
..
lsError = LS_DiscPrinter_ReleaseExclusiveUse( pDiscPrinter);
The C standard does not actually define behaviour for converting to and from function pointers. Explanations vary as to why; the most common being that not all architectures implement function pointers as simple pointers to data. On some architectures, functions may reside in an entirely different segment of memory that is unaddressable using a pointer to void.
The “recommended” way to use dlsym is:
LSError (*LS_DiscPrinter_ReleaseExclusiveUse)(LS_DiscPrinterHandle);
*(void **)&LS_DiscPrinter_ReleaseExclusiveUse = dlsym("LS_DiscPrinter_ReleaseExclusiveUse");
Read the rationale and example on the POSIX page for dlsym for more information.

Calling functions from within function(float *VeryBigArray,long SizeofArray) from within objC method fails with EXC_BAD_ACCESS

Ok I finally found the problem. It was inside the C function(CarbonTuner2) not the objC method. I was creating inside the function an array of the same size as the file size so if the filesize was big it created a really big array and my guess is that when I called another function from there, the local variables were put on the stack which created the EXC_BAD_ACCESS. What I did then is instead of using a variable to declare to size of the array I put the number directly. Then the code didnt even compile. it knew. The error wassomething like: Array size too big. I guess working 20+hours in a row isnt good XD But I am definitly gonna look into tools other than step by step debuggin to figure these ones out. Thanks for your help. Here is the code. If you divide gFileByteCount by 2 you dont get the error anymore:
// ConverterController.h
# import <Cocoa/Cocoa.h>
# import "Converter.h"
#interface ConverterController : NSObject {
UInt64 gFileByteCount ;
}
-(IBAction)ProcessFile:(id)sender;
void CarbonTuner2(long numSampsToProcess, long fftFrameSize, long osamp);
#end
// ConverterController.m
# include "ConverterController.h"
#implementation ConverterController
-(IBAction)ProcessFile:(id)sender{
UInt32 packets = gTotalPacketCount;//alloc a buffer of memory to hold the data read from disk.
gFileByteCount=250000;
long LENGTH=(long)gFileByteCount;
CarbonTuner2(LENGTH,(long)8192/2, (long)4*2);
}
#end
void CarbonTuner2(long numSampsToProcess, long fftFrameSize, long osamp)
{
long numFrames = numSampsToProcess / fftFrameSize * osamp;
float g2DFFTworksp[numFrames+2][2 * fftFrameSize];
double hello=sin(2.345);
}
Your crash has nothing to do with incompatibilities between C and ObjC.
And as previous posters said, you don't need to include math.h.
Run your code under gdb, and see where the crash happens by using backtrace.
Are you sure you're not sending bad arguments to the math functions?
E.g. this causes BAD_ACCESS:
double t = cos(*(double *)NULL);
Objective C is built directly on C, and the C underpinnings can and do work.
For an example of using math.h and parts of standard library from within an Objective C module, see:
http://en.wikibooks.org/wiki/Objective-C_Programming/syntax
There are other examples around.
Some care is needed around passing the variables around; use the C variables for the C and standard library calls; don't mix the C data types and Objective C data types incautiously. You'll usually want a conversion here.
If that is not the case, then please consider posting the code involved, and the error(s) you are receiving.
And with all respect due to Mr Hellman's response, I've hit errors when I don't have the header files included; I prefer to include the headers. But then, I tend to dial the compiler diagnostics up a couple of notches, too.
For what it's worth, I don't include math.h in my Cocoa app but have no problem using math functions (in C).
For example, I use atan() and don't get compiler errors, or run time errors.
Can you try this without including math.h at all?
First, you should add your code to your question, rather than posting it as an answer, so people can see what you're asking about. Second, you've got all sorts of weird problems with your memory management here - gFileByteCount is used to size a bunch of buffers, but it's set to zero, and doesn't appear to get re-set anywhere.
err = AudioFileReadPackets (fileID,
false, &bytesReturned, NULL,0,
&packets,(Byte *)rawAudio);
So, at this point, you pass a zero-sized buffer to AudioFileReadPackets, which prompty overruns the heap, corrupting the value of who knows what other variables...
fRawAudio =
malloc(gFileByteCount/(BITS/8)*sizeof(fRawAudio));
Here's another, minor error - you want sizeof(*fRawAudio) here, since you're trying to allocate an array of floats, not an array of float pointers. Fortunately, those entities are the same size, so it doesn't matter.
You should probably start with some example code that you know works (SpeakHere?), and modify it. I suspect there are other similar problems in the code yoou posted, but I don't have time to find them right now. At least get the rawAudio buffer appropriately-sized and use the values returned from AudioFileReadPackets appropriately.