TagLib Nim wrapper.
This commit is contained in:
		
							
								
								
									
										167
									
								
								src/main/nim/wdiwtlt/taglib.nim
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								src/main/nim/wdiwtlt/taglib.nim
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,167 @@ | ||||
| import std/[paths, strutils] | ||||
|  | ||||
| {.passl: "-ltag_c".} | ||||
| {.passc: "-ltag_c".} | ||||
|  | ||||
| type | ||||
|   TagLibFileType* {.size: sizeof(cint).} = enum | ||||
|     MPEG, OggVorbis, FLAC, MPC, OggFlac, WavPack, Speex, TrueAudio, MP4, ASF, | ||||
|     AIFF, WAV, APE, IT, Mod, S3M, XM, Opus, DSF, DSDIFF, SHORTEN | ||||
|  | ||||
|   TagLibID3v2Encoding* {.size: sizeof(cint).} = enum | ||||
|     Latin1, UTF16, UTF16BE, UTF8, Encoding | ||||
|  | ||||
|   CFile = pointer | ||||
|   CTag* = pointer | ||||
|   CAudioProperties = pointer | ||||
|  | ||||
|   TagLibFIle* = object | ||||
|     path*: Path | ||||
|     cfile*: CFile | ||||
|     tag*: CTag | ||||
|     ap*: CAudioProperties | ||||
|  | ||||
| {.push importc.} | ||||
| {.push cdecl.} | ||||
| proc taglib_set_strings_unicode*(unicode: cint) | ||||
| proc taglib_set_string_management_enabled*(enabled: cint) | ||||
| proc taglib_free*(p: pointer) | ||||
|  | ||||
| proc taglib_file_new(filename: cstring): CFile | ||||
| proc taglib_file_new_type(filename: cstring, `type`: TagLibFileType): CFile | ||||
| proc taglib_file_free(file: CFile) | ||||
| proc taglib_file_is_valid(file: CFile): cint | ||||
| proc taglib_file_tag(file: CFile): CTag | ||||
| proc taglib_file_audioproperties(file: CFile): CAudioProperties | ||||
| proc taglib_file_save(file: CFile): cint | ||||
|  | ||||
| proc taglib_tag_title(tag: CTag): cstring | ||||
| proc taglib_tag_artist(tag: CTag): cstring | ||||
| proc taglib_tag_album(tag: CTag): cstring | ||||
| proc taglib_tag_comment(tag: CTag): cstring | ||||
| proc taglib_tag_genre(tag: CTag): cstring | ||||
| proc taglib_tag_year(tag: CTag): cuint | ||||
| proc taglib_tag_track(tag: CTag): cuint | ||||
| proc taglib_tag_set_title(tag: CTag, title: cstring) | ||||
| proc taglib_tag_set_artist(tag: CTag, artist: cstring) | ||||
| proc taglib_tag_set_album(tag: CTag, album: cstring) | ||||
| proc taglib_tag_set_comment(tag: CTag, comment: cstring) | ||||
| proc taglib_tag_set_genre(tag: CTag, genre: cstring) | ||||
| proc taglib_tag_set_year(tag: CTag, year: cuint) | ||||
| proc taglib_tag_set_track(tag: CTag, year: cuint) | ||||
| proc taglib_tag_free_strings() | ||||
|  | ||||
| proc taglib_audioproperties_length(ap: CAudioProperties): cint | ||||
| proc taglib_audioproperties_bitrate(ap: CAudioProperties): cint | ||||
| proc taglib_audioproperties_samplerate(ap: CAudioProperties): cint | ||||
| proc taglib_audioproperties_channels(ap: CAudioProperties): cint | ||||
|  | ||||
| proc taglib_id3v2_set_default_text_encoding(encoding: TagLibID3v2Encoding) | ||||
|  | ||||
| proc taglib_property_set(file: CFile, prop: cstring, value: cstring) | ||||
| proc taglib_property_set_append(file: CFile, prop: cstring, value: cstring) | ||||
| #proc taglib_property_keys(file: CFile): cstring[] | ||||
| proc taglib_property_get(file: CFile, prop: cstring): cstring | ||||
| proc taglib_property_free(props: pointer) | ||||
|  | ||||
| {.pop.} # cdecl | ||||
| {.pop.} # importc | ||||
|  | ||||
| taglib_set_strings_unicode(1) | ||||
|  | ||||
| proc initTagLibFile(path: Path, cfile: CFile): TagLibFile = | ||||
|   if cfile.isNil: | ||||
|     raise newException(IOError, "Failed to open file: " & $path) | ||||
|  | ||||
|   if taglib_file_is_valid(cfile) < 0: | ||||
|     taglib_file_free(cfile) | ||||
|     raise newException(IOError, "Invalid TagLib file: " & $path) | ||||
|  | ||||
|   result.path = path | ||||
|   result.cfile = cfile | ||||
|   result.tag = taglib_file_tag(cfile) | ||||
|   result.ap = taglib_file_audioproperties(cfile) | ||||
|  | ||||
| proc openTags*(path: Path): TagLibFile = | ||||
|   ## Open a file and return a TagLibFile object. | ||||
|   let cfile = taglib_file_new(path.cstring) | ||||
|   initTagLibFile(path, cfile) | ||||
|  | ||||
| proc openTags*(path: Path, fileType: TagLibFileType): TagLibFile = | ||||
|   ## Open a file of a specific type and return a TagLibFile object. | ||||
|   let cfile = taglib_file_new_type(path.cstring, fileType) | ||||
|   initTagLibFile(path, cfile) | ||||
|  | ||||
| proc writeTags*(file: TagLibFile) = | ||||
|   ## Write tags to the file. | ||||
|   discard taglib_file_save(file.cfile) | ||||
|  | ||||
| proc close*(file: var TagLibFile) = | ||||
|   ## Close the file and free resources. | ||||
|   if not file.cfile.isNil: | ||||
|     taglib_tag_free_strings() | ||||
|     taglib_file_free(file.cfile) | ||||
|     file.cfile = nil | ||||
|     file.tag = nil | ||||
|     file.ap = nil | ||||
|  | ||||
| #proc `=destroy`*(file: TagLibFile) = | ||||
| #  ## Destroy the file and free resources. | ||||
| #  close(file) | ||||
|  | ||||
| {.push inline.} | ||||
| proc length*(file: TagLibFile): int = taglib_audioproperties_length(file.ap) | ||||
| proc bitrate*(file: TagLibFile): int = taglib_audioproperties_bitrate(file.ap) | ||||
| proc samplerate*(file: TagLibFile): int = taglib_audioproperties_samplerate(file.ap) | ||||
| proc channels*(file: TagLibFile): int = taglib_audioproperties_channels(file.ap) | ||||
|  | ||||
| proc title*(file: TagLibFile): string = $taglib_tag_title(file.tag) | ||||
| proc artist*(file: TagLibFile): string = $taglib_tag_artist(file.tag) | ||||
| proc album*(file: TagLibFile): string = $taglib_tag_album(file.tag) | ||||
| proc comment*(file: TagLibFile): string = $taglib_tag_comment(file.tag) | ||||
| proc genre*(file: TagLibFile): string = $taglib_tag_genre(file.tag) | ||||
| proc year*(file: TagLibFile): int = taglib_tag_year(file.tag).int | ||||
| proc track*(file: TagLibFile): int = taglib_tag_track(file.tag).int | ||||
|  | ||||
| proc `title=`*(file: var TagLibFile, title: string) = taglib_tag_set_title(file.tag, title.cstring) | ||||
| proc `artist=`*(file: var TagLibFile, artist: string) = taglib_tag_set_artist(file.tag, artist.cstring) | ||||
| proc `album=`*(file: var TagLibFile, album: string) = taglib_tag_set_album(file.tag, album.cstring) | ||||
| proc `comment=`*(file: var TagLibFile, comment: string) = taglib_tag_set_comment(file.tag, comment.cstring) | ||||
| proc `genre=`*(file: var TagLibFile, genre: string) = taglib_tag_set_genre(file.tag, genre.cstring) | ||||
| proc `year=`*(file: var TagLibFile, year: int) = taglib_tag_set_year(file.tag, year.cuint) | ||||
| proc `track=`*(file: var TagLibFile, track: int) = taglib_tag_set_track(file.tag, track.cuint) | ||||
|  | ||||
| proc albumArtist*(file: TagLibFile): string = | ||||
|   ## Get the album artist of the file. | ||||
|   let albumArtist = taglib_property_get(file.cfile, "ALBUMARTIST") | ||||
|   if albumArtist.isNil: | ||||
|     return "" | ||||
|   else: | ||||
|     return $albumArtist | ||||
|  | ||||
| proc `albumArtist=`*(file: var TagLibFile, albumArtist: string) = | ||||
|   ## Set the album artist of the file. | ||||
|   taglib_property_set(file.cfile, "ALBUMARTIST", albumArtist.cstring) | ||||
|  | ||||
| proc discNumber*(file: TagLibFile): int = | ||||
|   ## Get the disc number of the file. | ||||
|   let discNumber = taglib_property_get(file.cfile, "DISCNUMBER") | ||||
|   if discNumber.isNil: | ||||
|     return 0 | ||||
|   else: | ||||
|     return parseInt($discNumber) | ||||
|  | ||||
| proc `discNumber=`*(file: var TagLibFile, discNumber: int) = | ||||
|   ## Set the disc number of the file. | ||||
|   taglib_property_set(file.cfile, "DISCNUMBER".cstring, ($discNumber).cstring) | ||||
|  | ||||
| # Other properties we could use: | ||||
| # - SUBTITLE | ||||
| # - DATE | ||||
| # - COMPOSER | ||||
| # - TITLESORT | ||||
| # - ARTISTSORT | ||||
| # - ALBUMSORT | ||||
| # - ALBUMARTISTSORT | ||||
|  | ||||
| {.pop.} # inline | ||||
		Reference in New Issue
	
	Block a user