Re: OS X NSPasteBoard and Wave data
Re: OS X NSPasteBoard and Wave data
- Subject: Re: OS X NSPasteBoard and Wave data
- From: Kyle Sluder <email@hidden>
- Date: Thu, 10 Apr 2014 11:29:41 -0700
On Thu, Apr 10, 2014, at 09:57 AM, Charles Constant wrote:
> Hi Kyle et al,
>
>
> Thank you very much, Kyle, your email sorted me out. I changed my code to
> specify the Wave UTI from AVFoundation and pass in the bytes. Yay!
>
>
> I didn't have Garageband installed, but I do now, and it also only passes
> PCM audio internally. It's still a bit disappointing that I have no third
> party apps with which I can test pasting. I'm happy with the code now
> though, because any apps out there which want to should be able to get my
> data. I made a tiny test app just to test, and it plays audio from
> pasteboard just fine:
>
>
> NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
>
> NSData * wavefile_bytes = [pasteboard dataForType:AVFileTypeWAVE];
>
> NSSound *sound = [[NSSound alloc] initWithData:wavefile_bytes];
>
> [sound play];
>
>
> Beautiful, I can move on :)
You're quite welcome. But I suppose it's worth thinking about why these
apps may choose not to copy WAV data to the pasteboard.
When you write data to the pasteboard, it has to be copied out of your
process and into the pasteboard server's (pbs) memory. For uncompressed
WAV, that's a LOT of data being transferred over IPC, for a file that
might never be copied into another app.
A more sophisticated technique can help. Pasteboards can contain
multiple representations (sometimes called "flavors") of the same
content. For example, you can write the same audio data to the
pasteboard as an AIFF and a WAV, and the app you're pasting into can
choose which representation to paste.
One technique for avoiding unnecessary copying is to put some form of
small token on the pasteboard and mark it as a private type. Then when
you paste the data into the same app (which I would wager is where the
vast majority of copy/paste operations are actually performed), the app
first looks to see if the pasteboard contains data for the private type.
If it does, great! It can use the token data to perform the copy or move
without round-tripping through pbsāand sometimes without actually doing
any copying at all.
But what about copying into other apps?
This is where pasteboard providers come in. Rather than just calling
-setData:forType: on the NSPasteboardItem, you instead register a data
provider for the simple NSData-based UTIs, and only in the event that
pbs actually needs your data will you have to provide it.
That code would look something like this:
static NSString *const PrivateType =
@"com.mycompany.PrivatePasteboardType"; // be sure to define this in
your Info.plist
- (void)copy:(id)sender; {
id audioToken = /* ... */; // can be any plist type, like NSData or
NSValue
NSPasteboardItem *pbItem = [NSPasteboardItem new];
BOOL ok = [pbItem setPropertyList:audioToken forType:PrivateType];
ok = ok && [pbItem setDataProvider:self forTypes:@[AVFileTypeWAVE]];
if (ok) {
NSPasteboard *pboard = [NSPasteboard generalPasteboard];
[pboard clearContents];
ok = ok && [pboard writeObjects:@[pbItem]];
}
// handle failure if ! ok
}
- (void)pasteboard:(NSPasteboard *)pboard item:(NSPasteboardItem
*)pbItem provideDataForType:(NSString *)uti; {
id audioToken = [pbItem propertyListForType:PrivateType];
NSAssert(audioToken != nil, @"should have written an audio token!");
if (]uti isEqualToString:AVFileTypeWAVE]) {
NSData *wavData = WAVDataForToken(audioToken);
[pbItem setData:wavData forType:AVFileTypeWAVE];
} else {
NSAssert(NO, @"promised a data type we can't deliver!");
}
}
Of course, this requires that you are able to convert an audio token
into WAV data even if edits have happened in between the Copy and the
Paste. If your data model doesn't allow for that, you might be better
off with the simpler method I listed above.
Or perhaps GarageBand etc. have it right: copying audio data between
apps might be a misfeature. Especially when you consider the various
different ways the audio might be represented. (5.1, anyone?)
--Kyle Sluder
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden