diff --git a/Application/PlaybackController.m b/Application/PlaybackController.m index a62d41a4f..5ce8862bd 100644 --- a/Application/PlaybackController.m +++ b/Application/PlaybackController.m @@ -760,6 +760,14 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) { [player play:[pe URL] withUserInfo:pe withRGInfo:makeRGInfo(pe) startPaused:paused andSeekTo:[pe currentPosition]]; } +- (void)audioPlayer:(AudioPlayer *)player pushInfo:(NSDictionary *)info toTrack:(id)userInfo { + PlaylistEntry *pe = (PlaylistEntry *)userInfo; + [pe setMetadata:info]; + [playlistView refreshCurrentTrack:self]; + [self sendMetaData]; + [[NSNotificationCenter defaultCenter] postNotificationName:CogPlaybackDidBeginNotficiation object:pe]; +} + - (void)removeHDCD:(id)sender { MainWindow *mainWindow = (MainWindow *)appController.mainWindow; [mainWindow showHDCDLogo:NO]; diff --git a/Audio/AudioPlayer.h b/Audio/AudioPlayer.h index 97c89f183..14e127644 100644 --- a/Audio/AudioPlayer.h +++ b/Audio/AudioPlayer.h @@ -78,6 +78,8 @@ - (void)restartPlaybackAtCurrentPosition; +- (void)pushInfo:(NSDictionary *)info; + + (NSArray *)fileTypes; + (NSArray *)schemes; + (NSArray *)containerTypes; @@ -124,4 +126,5 @@ - (void)audioPlayer:(AudioPlayer *)player removeEqualizer:(AudioUnit)eq; - (void)audioPlayer:(AudioPlayer *)player sustainHDCD:(id)userInfo; - (void)audioPlayer:(AudioPlayer *)player restartPlaybackAtCurrentPosition:(id)userInfo; +- (void)audioPlayer:(AudioPlayer *)player pushInfo:(NSDictionary *)info toTrack:(id)userInfo; @end diff --git a/Audio/AudioPlayer.m b/Audio/AudioPlayer.m index 651f84a05..19f274d48 100644 --- a/Audio/AudioPlayer.m +++ b/Audio/AudioPlayer.m @@ -224,6 +224,10 @@ [self sendDelegateMethod:@selector(audioPlayer:restartPlaybackAtCurrentPosition:) withObject:[bufferChain userInfo] waitUntilDone:NO]; } +- (void)pushInfo:(NSDictionary *)info { + [self sendDelegateMethod:@selector(audioPlayer:pushInfo:toTrack:) withObject:info withObject:[bufferChain userInfo] waitUntilDone:NO]; +} + - (void)setShouldContinue:(BOOL)s { shouldContinue = s; diff --git a/Audio/Chain/BufferChain.h b/Audio/Chain/BufferChain.h index d989f0ad4..0e0c04794 100644 --- a/Audio/Chain/BufferChain.h +++ b/Audio/Chain/BufferChain.h @@ -77,4 +77,6 @@ - (void)restartPlaybackAtCurrentPosition; +- (void)pushInfo:(NSDictionary *)info; + @end diff --git a/Audio/Chain/BufferChain.m b/Audio/Chain/BufferChain.m index 83e724e86..4a3003cc3 100644 --- a/Audio/Chain/BufferChain.m +++ b/Audio/Chain/BufferChain.m @@ -264,4 +264,8 @@ [controller restartPlaybackAtCurrentPosition]; } +- (void)pushInfo:(NSDictionary *)info { + [controller pushInfo:info]; +} + @end diff --git a/Audio/Chain/InputNode.m b/Audio/Chain/InputNode.m index 6798b641c..f1df159ad 100644 --- a/Audio/Chain/InputNode.m +++ b/Audio/Chain/InputNode.m @@ -116,6 +116,18 @@ nodeLossless = [[properties valueForKey:@"encoding"] isEqualToString:@"lossless"]; } else if([keyPath isEqual:@"metadata"]) { // Inform something of metadata change + NSMutableDictionary *entryInfo = [NSMutableDictionary dictionaryWithCapacity:32]; + + NSDictionary *entryProperties = [decoder properties]; + if(entryProperties == nil) + return; + + [entryInfo addEntriesFromDictionary:entryProperties]; + [entryInfo addEntriesFromDictionary:[decoder metadata]]; + + NSDictionary * info = [NSDictionary dictionaryWithDictionary:entryInfo]; + + [controller pushInfo:info]; } } diff --git a/Audio/CogPluginMulti.m b/Audio/CogPluginMulti.m index 703a8771f..386cfe6f5 100644 --- a/Audio/CogPluginMulti.m +++ b/Audio/CogPluginMulti.m @@ -72,6 +72,11 @@ NSArray *sortClassesByPriority(NSArray *theClasses) { return nil; } +- (NSDictionary *)metadata { + if(theDecoder != nil) return [theDecoder metadata]; + return @{}; +} + - (int)readAudio:(void *)buffer frames:(UInt32)frames { if(theDecoder != nil) return [theDecoder readAudio:buffer frames:frames]; return 0; diff --git a/Audio/Plugin.h b/Audio/Plugin.h index 2a06f6141..0e2ed4933 100644 --- a/Audio/Plugin.h +++ b/Audio/Plugin.h @@ -37,6 +37,7 @@ // For KVO //- (void)setProperties:(NSDictionary *)p; - (NSDictionary *)properties; +- (NSDictionary *)metadata; // Only to be implemented for dynamic metadata, send events on change - (int)readAudio:(void *)buffer frames:(UInt32)frames; diff --git a/Playlist/PlaylistView.h b/Playlist/PlaylistView.h index 794535dcd..635194a2f 100644 --- a/Playlist/PlaylistView.h +++ b/Playlist/PlaylistView.h @@ -24,4 +24,6 @@ - (IBAction)scrollToCurrentEntry:(id)sender; +- (IBAction)refreshCurrentTrack:(id)sender; + @end diff --git a/Playlist/PlaylistView.m b/Playlist/PlaylistView.m index f2e7694bb..79bad538a 100644 --- a/Playlist/PlaylistView.m +++ b/Playlist/PlaylistView.m @@ -405,6 +405,11 @@ return [super validateUserInterfaceItem:anItem]; } +- (IBAction)refreshCurrentTrack:(id)sender { + unsigned long columns = [[self tableColumns] count]; + [self reloadDataForRowIndexes:[NSIndexSet indexSetWithIndex:[[playlistController currentEntry] index]] columnIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, columns)]]; +} + #if 0 - (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal { diff --git a/Plugins/APL/APLDecoder.m b/Plugins/APL/APLDecoder.m index cc98d51d9..3d586edf4 100644 --- a/Plugins/APL/APLDecoder.m +++ b/Plugins/APL/APLDecoder.m @@ -28,7 +28,11 @@ // Need to alter length [properties setObject:[NSNumber numberWithLong:trackLength] forKey:@"totalFrames"]; - return properties; + return [NSDictionary dictionaryWithDictionary:properties]; +} + +- (NSDictionary *)metadata { + return @{}; } - (BOOL)open:(id)s { diff --git a/Plugins/AdPlug/AdPlug/AdPlugDecoder.mm b/Plugins/AdPlug/AdPlug/AdPlugDecoder.mm index ab1a65acb..ea9cf47ab 100644 --- a/Plugins/AdPlug/AdPlug/AdPlugDecoder.mm +++ b/Plugins/AdPlug/AdPlug/AdPlugDecoder.mm @@ -92,6 +92,10 @@ static CAdPlugDatabase *g_database = NULL; @"endian": @"host"}; } +- (NSDictionary *)metadata { + return @{}; +} + - (int)readAudio:(void *)buf frames:(UInt32)frames { int total = 0; bool dont_loop = !IsRepeatOneSet(); diff --git a/Plugins/CoreAudio/CoreAudioDecoder.m b/Plugins/CoreAudio/CoreAudioDecoder.m index 3ea2c37fc..df352d8f1 100644 --- a/Plugins/CoreAudio/CoreAudioDecoder.m +++ b/Plugins/CoreAudio/CoreAudioDecoder.m @@ -402,4 +402,8 @@ static SInt64 getSizeProc(void *clientData) { @"encoding": _audioFile_is_lossy ? @"lossy" : @"lossless"}; } +- (NSDictionary *)metadata { + return @{}; +} + @end diff --git a/Plugins/CueSheet/CueSheetDecoder.m b/Plugins/CueSheet/CueSheetDecoder.m index d7ae86b8b..0dac57c5c 100644 --- a/Plugins/CueSheet/CueSheetDecoder.m +++ b/Plugins/CueSheet/CueSheetDecoder.m @@ -40,7 +40,11 @@ // Need to alter length [properties setObject:[NSNumber numberWithLong:(trackEnd - trackStart)] forKey:@"totalFrames"]; - return properties; + return [NSDictionary dictionaryWithDictionary:properties]; +} + +- (NSDictionary *)metadata { + return @{}; } - (BOOL)open:(id)s { diff --git a/Plugins/FFMPEG/FFMPEGDecoder.m b/Plugins/FFMPEG/FFMPEGDecoder.m index 9fcc09be3..86c08b398 100644 --- a/Plugins/FFMPEG/FFMPEGDecoder.m +++ b/Plugins/FFMPEG/FFMPEGDecoder.m @@ -647,6 +647,10 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) { @"encoding": lossy ? @"lossy" : @"lossless"}; } +- (NSDictionary *)metadata { + return @{}; +} + + (NSArray *)fileTypes { return @[@"wma", @"asf", @"tak", @"mp4", @"m4a", @"aac", @"mp3", @"mp2", @"m2a", @"mpa", @"ape", @"ac3", @"dts", @"dtshd", @"wav", @"tta", @"vqf", @"vqe", @"vql", @"ra", @"rm", @"rmj", @"mka", @"weba"]; } diff --git a/Plugins/Flac/FlacDecoder.m b/Plugins/Flac/FlacDecoder.m index 53d29bca1..a260f4e95 100644 --- a/Plugins/Flac/FlacDecoder.m +++ b/Plugins/Flac/FlacDecoder.m @@ -366,6 +366,10 @@ void ErrorCallback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorS @"encoding": @"lossless"}; } +- (NSDictionary *)metadata { + return @{}; +} + + (NSArray *)fileTypes { return @[@"flac"]; } diff --git a/Plugins/GME/GameDecoder.m b/Plugins/GME/GameDecoder.m index d98773653..b3e6e28ca 100644 --- a/Plugins/GME/GameDecoder.m +++ b/Plugins/GME/GameDecoder.m @@ -151,6 +151,10 @@ gme_err_t readCallback(void *data, void *out, int count) { @"encoding": @"synthesized"}; } +- (NSDictionary *)metadata { + return @{}; +} + - (int)readAudio:(void *)buf frames:(UInt32)frames { int numSamples = frames * 2; // channels = 2 diff --git a/Plugins/Hively/Hively/HVLDecoder.m b/Plugins/Hively/Hively/HVLDecoder.m index 2d45a339a..7e13d4171 100644 --- a/Plugins/Hively/Hively/HVLDecoder.m +++ b/Plugins/Hively/Hively/HVLDecoder.m @@ -91,6 +91,10 @@ static void oneTimeInit(void) { @"encoding": @"synthesized"}; } +- (NSDictionary *)metadata { + return @{}; +} + - (int)readAudio:(void *)buf frames:(UInt32)frames { BOOL repeatone = IsRepeatOneSet(); diff --git a/Plugins/MIDI/MIDI/MIDIDecoder.mm b/Plugins/MIDI/MIDI/MIDIDecoder.mm index 787f612d8..2ec9a23a7 100644 --- a/Plugins/MIDI/MIDI/MIDIDecoder.mm +++ b/Plugins/MIDI/MIDI/MIDIDecoder.mm @@ -109,6 +109,10 @@ static OSType getOSType(const char *in_) { @"encoding": @"synthesized"}; } +- (NSDictionary *)metadata { + return @{}; +} + - (BOOL)initDecoder { NSString *soundFontPath = @""; diff --git a/Plugins/Musepack/MusepackDecoder.m b/Plugins/Musepack/MusepackDecoder.m index 56d895a8e..b505a2692 100644 --- a/Plugins/Musepack/MusepackDecoder.m +++ b/Plugins/Musepack/MusepackDecoder.m @@ -191,6 +191,10 @@ mpc_bool_t CanSeekProc(mpc_reader *p_reader) { @"encoding": @"lossy"}; } +- (NSDictionary *)metadata { + return @{}; +} + + (NSArray *)fileTypes { return @[@"mpc"]; } diff --git a/Plugins/OpenMPT.old/OpenMPT/OMPTDecoder.mm b/Plugins/OpenMPT.old/OpenMPT/OMPTDecoder.mm index 0bd1234ce..31cf07288 100644 --- a/Plugins/OpenMPT.old/OpenMPT/OMPTDecoder.mm +++ b/Plugins/OpenMPT.old/OpenMPT/OMPTDecoder.mm @@ -104,6 +104,10 @@ static void g_push_archive_extensions(std::vector &list) { @"encoding": @"synthesized"}; } +- (NSDictionary *)metadata { + return @{}; +} + - (int)readAudio:(void *)buf frames:(UInt32)frames { mod->set_repeat_count(IsRepeatOneSet() ? -1 : 0); diff --git a/Plugins/OpenMPT/OpenMPT/OMPTDecoder.mm b/Plugins/OpenMPT/OpenMPT/OMPTDecoder.mm index d17c1d4bf..552b9c04a 100644 --- a/Plugins/OpenMPT/OpenMPT/OMPTDecoder.mm +++ b/Plugins/OpenMPT/OpenMPT/OMPTDecoder.mm @@ -101,6 +101,10 @@ static void g_push_archive_extensions(std::vector &list) { @"encoding": @"synthesized"}; } +- (NSDictionary *)metadata { + return @{}; +} + - (int)readAudio:(void *)buf frames:(UInt32)frames { mod->set_repeat_count(IsRepeatOneSet() ? -1 : 0); diff --git a/Plugins/Opus/Opus/OpusDecoder.m b/Plugins/Opus/Opus/OpusDecoder.m index 6978d7b60..5b898a447 100644 --- a/Plugins/Opus/Opus/OpusDecoder.m +++ b/Plugins/Opus/Opus/OpusDecoder.m @@ -188,6 +188,10 @@ opus_int64 sourceTell(void *_stream) { @"encoding": @"lossy"}; } +- (NSDictionary *)metadata { + return @{}; +} + + (NSArray *)fileTypes { return @[@"opus", @"ogg"]; } diff --git a/Plugins/Shorten/ShortenDecoder.mm b/Plugins/Shorten/ShortenDecoder.mm index c3ae63aa1..7477ded78 100644 --- a/Plugins/Shorten/ShortenDecoder.mm +++ b/Plugins/Shorten/ShortenDecoder.mm @@ -87,6 +87,10 @@ @"encoding": @"lossless"}; } +- (NSDictionary *)metadata { + return @{}; +} + + (NSArray *)fileTypes { return @[@"shn"]; } diff --git a/Plugins/SilenceDecoder/SilenceDecoder/SilenceDecoder.m b/Plugins/SilenceDecoder/SilenceDecoder/SilenceDecoder.m index 28ae9d307..7994ff2a5 100644 --- a/Plugins/SilenceDecoder/SilenceDecoder/SilenceDecoder.m +++ b/Plugins/SilenceDecoder/SilenceDecoder/SilenceDecoder.m @@ -46,6 +46,10 @@ enum { channels = 2 }; @"encoding": @"synthesized"}; } +- (NSDictionary *)metadata { + return @{}; +} + - (int)readAudio:(void *)buf frames:(UInt32)frames { int total = frames; diff --git a/Plugins/Vorbis/VorbisDecoder.m b/Plugins/Vorbis/VorbisDecoder.m index 582a11dc2..703781de4 100644 --- a/Plugins/Vorbis/VorbisDecoder.m +++ b/Plugins/Vorbis/VorbisDecoder.m @@ -171,6 +171,10 @@ long sourceTell(void *datasource) { @"encoding": @"lossy"}; } +- (NSDictionary *)metadata { + return @{}; +} + + (NSArray *)fileTypes { return @[@"ogg"]; } diff --git a/Plugins/WavPack/WavPackDecoder.m b/Plugins/WavPack/WavPackDecoder.m index fb2e02590..0850d1a56 100644 --- a/Plugins/WavPack/WavPackDecoder.m +++ b/Plugins/WavPack/WavPackDecoder.m @@ -294,6 +294,10 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount) { @"encoding": isLossy ? @"lossy" : @"lossless"}; } +- (NSDictionary *)metadata { + return @{}; +} + + (NSArray *)fileTypes { return @[@"wv", @"wvp"]; } diff --git a/Plugins/libvgmPlayer/libvgmDecoder.mm b/Plugins/libvgmPlayer/libvgmDecoder.mm index 401d31969..13c3a6381 100644 --- a/Plugins/libvgmPlayer/libvgmDecoder.mm +++ b/Plugins/libvgmPlayer/libvgmDecoder.mm @@ -189,6 +189,10 @@ const int masterVol = 0x10000; // Fixed point 16.16 @"encoding": @"synthesized"}; } +- (NSDictionary *)metadata { + return @{}; +} + - (int)readAudio:(void*)buf frames:(UInt32)frames { if([self trackEnded]) return 0; diff --git a/Plugins/sidplay/SidDecoder.mm b/Plugins/sidplay/SidDecoder.mm index 461fa2754..084baba42 100644 --- a/Plugins/sidplay/SidDecoder.mm +++ b/Plugins/sidplay/SidDecoder.mm @@ -199,6 +199,10 @@ static void sidTuneLoader(const char *fileName, std::vector &bufferRef) @"encoding": @"synthesized"}; } +- (NSDictionary *)metadata { + return @{}; +} + - (int)readAudio:(void *)buf frames:(UInt32)frames { int total = 0; int16_t *sampleBuffer = (int16_t *)buf; diff --git a/Plugins/vgmstream/vgmstream/VGMDecoder.m b/Plugins/vgmstream/vgmstream/VGMDecoder.m index 929627f9f..a14d2ef6c 100644 --- a/Plugins/vgmstream/vgmstream/VGMDecoder.m +++ b/Plugins/vgmstream/vgmstream/VGMDecoder.m @@ -295,6 +295,10 @@ static NSString *get_description_tag(const char *description, const char *tag, c @"encoding": @"lossy/lossless"}; } +- (NSDictionary *)metadata { + return @{}; +} + - (int)readAudio:(void *)buf frames:(UInt32)frames { UInt32 framesMax = frames; UInt32 framesDone = 0;