Advertisement
Guest User

Audacity label tool

a guest
May 20th, 2019
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 13.82 KB | None | 0 0
  1. #! C:\Python\Python37\python.exe
  2. #! coding: utf-8
  3. #! python3
  4. # Black Cat 2019
  5. # Licence cc-by-nc-sa
  6. # Adds timestamp in format HH_MM_SS_ from precise audacity timestamps
  7. # Also, checks for type and abbreviations
  8. # And do a freaking mess of other things
  9.  
  10. import difflib
  11.  
  12. VERSION = 0.9
  13.  
  14. def timestampToTime( timestamp ) :
  15.     hours = int( timestamp/3600 )
  16.     minutes = int( (timestamp - (3600*hours)) / 60 )
  17.     seconds = int( (timestamp - (60*minutes) - (3600*hours)) )
  18.     millis = int( (timestamp - int(timestamp)) * 1000 )
  19.     fractional = timestamp - int(timestamp)
  20.     return (hours, minutes, seconds, millis, fractional)
  21.  
  22.  
  23. def timeToTimestamp( hours=0, minutes=0, seconds=0, millis=0 ) :
  24.     return (3600*hours)+(60*minutes)+seconds+(millis/1000)
  25.    
  26.  
  27.  
  28. def likeness( a="", b="" ) :
  29.     likeness = difflib.SequenceMatcher(None, a, b).ratio()
  30.     return likeness
  31.  
  32. # This is so dirty and lazy. Please, uses a real library like "inflect"
  33. def num2str( num=0 ) :
  34.     string = ""
  35.     if abs( num ) > 9999999999 :
  36.         error( "num2str : (positive or negative) Number to big sorry my coder was lazy" )
  37.         string = str(num)
  38.     elif num == 0 :
  39.         string = "zero"
  40.     else :
  41.         # Power Of Ten = 0
  42.         units = ["", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "TEN", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"]
  43.         # Power Of Ten = 1
  44.         decades = ["", "ten", "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety"]
  45.         hundreds = "hundred"
  46.         # Power Of Ten [0, 3, 6, 9]
  47.         thousands = ["", "thousand", "million", "billion"]
  48.        
  49.         n = abs(num)
  50.         t = 0
  51.         string = ""
  52.         while n > 0 :
  53.             strHun = ""
  54.             hun = n % 1000
  55.             n = int(n/1000)
  56.            
  57.             u = hun % 10
  58.             d = int((hun % 100)/10)
  59.             c = int(hun/100)
  60.            
  61.             if d < 2 :
  62.                 strHun = units[(10*d)+u]
  63.             else :
  64.                 strHun = decades[d] + " " + units[u]
  65.            
  66.             if c > 0 :
  67.                 strHun = units[c] + " hundred and " + strHun
  68.            
  69.             if t != 0 :
  70.                 strHun = strHun + " " + thousands[t] + ", "
  71.             t += 1
  72.            
  73.             if string != "" :
  74.                 string = " " + string
  75.             string = strHun + string
  76.        
  77.         if num < 0 :
  78.             string = "minus "
  79.        
  80.     return string
  81.  
  82. #==============================================================================
  83. # Eye candy
  84. #==============================================================================
  85. def info( text="?" ) :
  86.     global ERROR_LEVEL
  87.     if ERROR_LEVEL > 2 :
  88.         print( "   info   : "+text )
  89.  
  90. def good( text="?" ) :
  91.     global ERROR_LEVEL
  92.     if ERROR_LEVEL > 1 :
  93.         print( "   good   : "+text )
  94.  
  95. def warning( text="?" ) :
  96.     global ERROR_LEVEL
  97.     if ERROR_LEVEL > 0 :
  98.         print( "[warning] : "+text )
  99.  
  100. def error( text="?" ) :
  101.     print( "[ ERROR ] : "+text )
  102.  
  103. def draw_spacer(char="=") :
  104.     print( char*79 )
  105.  
  106.  
  107. #==============================================================================
  108. # Parameters
  109. INPUT = "labelsRaw_Test.txt"
  110. #INPUT = r"D:\PPPV\Cut\MLP\0102\0102Raw.txt"
  111.  
  112. # Shall the program save the file or just checks for goofs?
  113. SAVE_FILE = True
  114. OUTPUT = "labels.txt"
  115.  
  116. # Shall the program autoreplace typos?
  117. REPLACE_TYPO = True
  118.  
  119. # Shall the program autoreplace leftover abbreviations?
  120. REPLACE_LEFTOVER = True
  121.  
  122. # Shall the program autoreplace ending punctuation?
  123. REPLACE_ENDING_PUNCTUATION = True
  124.  
  125. # Shall the program autoreplace transcript abbreviations?
  126. REPLACE_ABBREVIATIONS = True
  127.  
  128. # Error level to display or not stuff.
  129. # 0 : errors only
  130. # 1 : errors and warning
  131. # 2 : errors, warning and good
  132. # 3 : errors, warning, good and infos
  133. ERROR_LEVEL = 3
  134.  
  135.  
  136. # Shall not modify after this line
  137. #=============================================================================
  138. draw_spacer()
  139. print( "Welcome to label checker V "+str(VERSION) )
  140. print( "Let me bitch about your typo and other mistakes..." )
  141. print()
  142. print( "input\t: " + INPUT )
  143. print( "output\t: " + OUTPUT )
  144. bools = ["Nope", "Eyup"]
  145. print( "Replace typos    \t: " + bools[int(REPLACE_TYPO)] )
  146. print( "Replace leftovers\t: " + bools[int(REPLACE_LEFTOVER)] )
  147. print( "Replace punctuation\t: " + bools[int(REPLACE_ENDING_PUNCTUATION)] )
  148. print( "Replace abbreviations\t: " + bools[int(REPLACE_ABBREVIATIONS)] )
  149.  
  150. if (int(REPLACE_TYPO) + int(REPLACE_LEFTOVER) + int(REPLACE_ENDING_PUNCTUATION) + int(REPLACE_ABBREVIATIONS) ) > 3 :
  151.     print( "(You shouldn't put that much trust in me...)" )
  152.  
  153. whine = ["warning only", "warning and error", "boringly verbose", "worst than your ex"]
  154. print( "Whining level\t: " + whine[ERROR_LEVEL] )
  155. draw_spacer()
  156. print()
  157.  
  158. abbreviations = {
  159.     "names" : {
  160.         "Twilight":["twilight sparkle", "ts", "twi"],
  161.         "Pinkie":["pinkie pie", "pp"],
  162.         "Applejack":["aj", "apl"],
  163.         "Rainbow":["rainbow dash", "rd"],
  164.         "Rarity":["ra", "rar"],
  165.         "Fluttershy":["fs", "flu"],
  166.         "Spike":["sp", "spi"],
  167.         "Celestia":["princess celestia", "ce", "cel", "celly"],
  168.         "Luna":["princess luna", "lu"],
  169.         "Apple Bloom":["ab"],
  170.         "Sweetie Belle":["sb"],
  171.         "Scootaloo":["sc", "chicken"],
  172.         "Diamond Tiarra":["dt"],
  173.         "Silver Spoon":["ss"],
  174.         "Cheerlee":["ch"],
  175.         "Iron Will":["i"],
  176.         "Cadence":["princess cadence", "cad"],
  177.         "Shining Armor":["sa"],
  178.         "Chrysalis":["queen chrysalis", "cr", "bug butt"],
  179.         "Nightmare Moon":["nm"],
  180.         "Grany Smith":["gs"],
  181.         "Mayor Mare":["mm"],
  182.         "Babs Seed":["bs"],
  183.         "Spitfire":["sf"],
  184.         "Lightning Dust":["ld"]
  185.     },
  186.     "moods" : {
  187.         "Neutral":["n"],
  188.         "Happy":["h"],
  189.         "Amused":["am"],
  190.         "Sad":["s"],
  191.         "Annoyed":["a"],
  192.         "Angry":["ag"],
  193.         "Disgust":["d"],
  194.         "Sarcastic":["sa"],
  195.         "Smug":["sm"],
  196.         "Fear":["f"],
  197.         "Anxious":["ax"],
  198.         "Confused":["c"],
  199.         "Surprised":["su"],
  200.         "Tired":["t"],
  201.         "Whispering":["w"],
  202.         "Shouting":["sh"],
  203.         "Whining":["wh"]
  204.     },
  205.     "noise" : {
  206.         "Noisy":["q", "n"],
  207.         "Very Noisy":["qq", "vn"]
  208.     },
  209.     "transcript" : {
  210.         "mister" : "mr",
  211.         "miss" : "ms"
  212.     }
  213. }
  214.  
  215.  
  216. characters = []
  217.  
  218. # Reads the labels file
  219. try :
  220.     file = open( INPUT, "r" )
  221.     labelData = file.readlines()
  222.    
  223. except NameError as e :
  224.     error( "File " + INPUT + " can't be found." )
  225.    
  226. except IOError as e :
  227.     error( "IO error {0} when trying to access the file : {1}".format( e.errno, e.strerror ) )
  228.    
  229. finally :
  230.     file.close()
  231.    
  232.  
  233. # Gather informations from label file
  234.  
  235. episode = {}
  236. lines = []
  237.  
  238. #-----------------------------------------------------------------------------
  239. # Work on each label
  240.  
  241. for index in range( len(labelData) ) :
  242.     # By default, the line shall be defective to be absolutely sure. But I'm lazy
  243.     rottenLine = False
  244.    
  245.     line = labelData[index]
  246.    
  247.     if line.rstrip() == "" :
  248.         warning( "Empty line " + str(index +1 ) )
  249.         rottenLine = True
  250.     else :
  251.        
  252.         if line.count("\t") != 2 :
  253.             error( "Malformed line " + str(index +1 ) + " : Check tabulations on label" )
  254.             rottenLine = True
  255.         else :
  256.             start, end, label = line.split( "\t" )
  257.            
  258.             start = start
  259.             end = end
  260.             label = label.rstrip()
  261.            
  262.             length = float(end) - float(start)
  263.             hour, minute, second, milli, trash = timestampToTime( float(start) )
  264.            
  265.             entry = "{hour:0>2}{minute:0>2}{second:0>2}".format( hour=hour, minute=minute, second=second)
  266.            
  267.             #-----------------------------------------------------------------
  268.             # Checks the label content
  269.             underscoreNumber = label.count("_")
  270.            
  271.             if underscoreNumber == 6 :
  272.                 info( "Line " + str(index +1) + " : Timestamp already here" )
  273.                 h, m, s, character, moods, noise, transcript = label.split( "_" )
  274.                
  275.             elif underscoreNumber == 3 :
  276.                 character, moods, noise, transcript = label.split( "_" )
  277.                
  278.             else :
  279.                 error( "Malformed line " +str(index +1 ) + " : Check underscores" )
  280.                 rottenLine = True
  281.                
  282.             if not rottenLine :
  283.                 #-------------------------------------------------------------
  284.                 # Character checks
  285.                 if character != "" :
  286.                     # Typo checks
  287.                     for char in abbreviations["names"] :
  288.                         if character != char :
  289.                             if likeness( character, char ) > 0.85 :
  290.                                 if REPLACE_TYPO :
  291.                                     info( "Line " + str(index +1 ) + " name : " + character + " replaced by " + char )
  292.                                     character = char
  293.                                 else :
  294.                                     warning( "Line " + str(index +1 ) + " name : " + character + " used. Do you mean " + char + "?" )
  295.                    
  296.                     # Abbreviations checks
  297.                     for char in abbreviations["names"] :
  298.                         if character.lower() in abbreviations["names"][char] :
  299.                             if REPLACE_LEFTOVER :
  300.                                 info( "Line " + str(index +1 ) + " name : " + character + " replaced by " + char )
  301.                                 character = char
  302.                             else :
  303.                                 warning( "Line " + str(index +1 ) + " name : " + character + " used. Do you mean " + char + "?" )
  304.                 else :
  305.                     error( "Line " + str(index +1 ) + " : No character" )
  306.                     rottenLine = True
  307.                
  308.                 #-------------------------------------------------------------
  309.                 # Mood checks
  310.                 if moods != "" :
  311.                     m = moods.split()
  312.                    
  313.                     # For each mood in the label
  314.                     for id in range( len(m) ) :
  315.                        
  316.                         # Typo checks
  317.                         for mood in abbreviations["moods"] :
  318.                             if m[id] != mood :
  319.                                 if likeness( m[id], mood ) > 0.85 :
  320.                                     if REPLACE_TYPO :
  321.                                         info( "Line " + str(index +1 ) + " mood : " + m[id] + " replaced by " + mood )
  322.                                         m[id] = mood
  323.                                     else :
  324.                                         warning( "Line " + str(index +1 ) + " mood : " + m[id] + " used. Do you mean " + mood + "?" )
  325.                        
  326.                         # Abbreviations checks
  327.                         # Checks against each known mood leftover abbreviation
  328.                         for mood in abbreviations["moods"] :
  329.                             if m[id].lower() in abbreviations["moods"][mood] :
  330.                                 if REPLACE_LEFTOVER :
  331.                                     info( "Line " + str(index +1 ) + " mood : " + m[id] + " replaced by " + mood )
  332.                                     m[id] = mood
  333.                                 else :
  334.                                     warning( "Line " + str(index +1 ) + " mood : " + m[id] + " used. Do you mean " + mood + "?" )
  335.                        
  336.                         # Checks if the mod is known
  337.                         m[id] = m[id].capitalize()
  338.                         if m[id] not in abbreviations["moods"] :
  339.                             warning( "Line "+str(index +1)+" mood : '" + m[id] + "' unknown. Can't check it" )
  340.                    
  341.                     # Construct back the string. Obviously a more pythonic way exists, but I'm a lazy fuck.
  342.                     moods = ""
  343.                     for id in range( len(m) ) :
  344.                         if id > 0 :
  345.                             moods += " "
  346.                         moods += m[id]
  347.                    
  348.                 else :
  349.                     error( "Line " + str(index +1 ) + " : No mood" )
  350.                     rottenLine = True
  351.                
  352.                 #-------------------------------------------------------------
  353.                 # Noise checks
  354.                 if noise != "" :
  355.                     for n in abbreviations["noise"] :
  356.                        
  357.                         # Abbreviation check
  358.                         if noise in abbreviations["noise"][n] :
  359.                             if REPLACE_LEFTOVER :
  360.                                 info( "Line " + str(index +1 ) + " noise : " + noise + " replaced by " + n )
  361.                                 noise = n
  362.                             else :
  363.                                 warning( "Line " + str(index +1 ) + " noise : " + noise + " used. Do you mean " + n + "?" )
  364.                        
  365.                         # Typo check
  366.                         if noise != n :
  367.                             if likeness( noise.lower(), n.lower() ) > 0.85 :
  368.                                 if REPLACE_TYPO :
  369.                                     info( "Line " + str(index +1) + " noise : " + noise + " replaced by " + n )
  370.                                     noise = n
  371.                                 else :
  372.                                     warning( "Line " + str(index +1) + " noise : " + noise + "used. Do you mean " + n + "?" )
  373.                        
  374.                    
  375.                     if noise.lower() not in ["", "noisy", "very noisy"] :
  376.                         error( "Line " + str(index +1) + " noise is " + noise + " ; shall be nothing, 'noisy' or 'very noisy'" )
  377.                         rottenLine = True
  378.                
  379.                 #-------------------------------------------------------------
  380.                 # Transcript checks
  381.                 if transcript != "" :
  382.                    
  383.                     # Check for ending punctuation
  384.                     if transcript[-1] not in ",.!?" :
  385.                         ending = ""
  386.                         m = moods.split()
  387.                         for mood in m :
  388.                             if mood in ["Happy", "Angry", "Fear", "Anxious", "Surprised", "Shouting"] :
  389.                                 if ending.count("!") == 0 :
  390.                                     ending += "!"
  391.                             elif mood in ["Annoyed", "Sarcastic", "Confused"] :
  392.                                 if ending.count("?") == 0 :
  393.                                     ending += "?"
  394.                        
  395.                         if ending == "" :
  396.                             ending = "."
  397.                        
  398.                         if REPLACE_ENDING_PUNCTUATION :
  399.                             info( "Line " + str(index +1) + " trans : No punctuation. Guestimate based on mood : " + ending + " (please, do check, I'm not good with emotions...)" )
  400.                             transcript += ending
  401.                         else :
  402.                             warning( "Line " + str(index +1) + " trans : No punctuation. (Guestimate based on mood : "+ending+" )" )
  403.                    
  404.                     # Check for numbers and abbreviations
  405.                     words = transcript.split( " " )
  406.                     trans = ""
  407.                     for word in words :
  408.                        
  409.                         # Numbers
  410.                         if word.isdigit() :
  411.                             if REPLACE_ABBREVIATIONS :
  412.                                 number = num2str( int(word) )
  413.                                 info( "Line "+str(index +1)+" : "+ word+" expanded to " + number )
  414.                                 word = number # Yay, that's duck typing! (kidding, both are string, but you got the joke, right? Ri-right?)
  415.                        
  416.                         for abb in abbreviations["transcript"] :
  417.                             #if abbreviations["transcript"][abb] in word :
  418.                             if abbreviations["transcript"][abb] == word :
  419.                                 info( "Line "+str(index +1)+" : " + word+" expanded to " + abb)
  420.                                 word = abb
  421.                        
  422.                         # Rebuild the transcript
  423.                         if trans != "" :
  424.                             trans += " "
  425.                         trans += word
  426.                    
  427.                     transcript = trans
  428.                    
  429.                 else :
  430.                     error( "Line " + str(index +1 ) + " : No transcript" )
  431.                     rottenLine = True
  432.                
  433.     #-------------------------------------------------------------------------
  434.     # If no errors, keep the line
  435.     if not rottenLine :
  436.         lines.append( f"{start}\t{end}\t{hour:0>2}_{minute:0>2}_{second:0>2}_{character}_{moods}_{noise}_{transcript}" )
  437.     else :
  438.         info( "Line " + str(index +1 ) + " dropped." )
  439.    
  440.  
  441.  
  442. # Save to file if asked
  443. if SAVE_FILE :
  444.     try :
  445.         file = open( OUTPUT, "w" )
  446.         for line in lines :
  447.             file.write( line + "\n" )
  448.         info( "File saved" )
  449.        
  450.     except NameError as e :
  451.         error( "File " + OUTPUT + " can't be found." )
  452.        
  453.     except IOError as e :
  454.         error( "IO error {0} when trying to access the file : {1}".format( e.errno, e.strerror ) )
  455.        
  456.     finally :
  457.         file.close()
  458. else :
  459.     for line in lines :
  460.         print( line )
  461.     info( "Nothing saved to the disk." )
  462.  
  463. input("Press enter to quit.")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement