mirror of
https://github.com/wassname/pysle.git
synced 2026-08-20 12:40:18 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a36d7c8d17 | ||
|
|
65ac652dea | ||
|
|
ee08c347d5 | ||
|
|
c16c68a6ac | ||
|
|
bc4f19c74c | ||
|
|
c19cde7165 | ||
|
|
38ebc7f3f9 | ||
|
|
102e8a7488 | ||
|
|
6b786cd00a | ||
|
|
fb1e638cb8 | ||
|
|
e5acdfce30 | ||
|
|
d47c312de7 | ||
|
|
303d9bfcf2 | ||
|
|
9c0ccd5748 | ||
|
|
393182500e |
+52
-4
@@ -3,6 +3,9 @@
|
|||||||
pysle
|
pysle
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
.. image:: https://img.shields.io/badge/license-MIT-blue.svg?
|
||||||
|
:target: http://opensource.org/licenses/MIT
|
||||||
|
|
||||||
Pronounced like 'p' + 'isle'.
|
Pronounced like 'p' + 'isle'.
|
||||||
|
|
||||||
An interface for the ILSEX (international speech lexicon) dictionary,
|
An interface for the ILSEX (international speech lexicon) dictionary,
|
||||||
@@ -37,6 +40,26 @@ What can you do with this library?
|
|||||||
pysle.syllabifyTextgrid(isleDict, praatioTextgrid, "words", "phones")
|
pysle.syllabifyTextgrid(isleDict, praatioTextgrid, "words", "phones")
|
||||||
|
|
||||||
|
|
||||||
|
Major revisions
|
||||||
|
================
|
||||||
|
|
||||||
|
Ver 1.3 (March 15, 2016)
|
||||||
|
|
||||||
|
- added indicies for stressed vowels
|
||||||
|
|
||||||
|
Ver 1.2 (June 20, 2015)
|
||||||
|
|
||||||
|
- Python 3.x support
|
||||||
|
|
||||||
|
Ver 1.1 (January 30, 2015)
|
||||||
|
|
||||||
|
- word lookup ~65 times faster
|
||||||
|
|
||||||
|
Ver 1.0 (October 23, 2014)
|
||||||
|
|
||||||
|
- first public release.
|
||||||
|
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
================
|
================
|
||||||
|
|
||||||
@@ -50,6 +73,8 @@ Requirements
|
|||||||
|
|
||||||
- ``Python 2.7.*`` or above
|
- ``Python 2.7.*`` or above
|
||||||
|
|
||||||
|
- ``Python 3.3.*`` or above
|
||||||
|
|
||||||
- The `praatIO <https://github.com/timmahrt/praatIO>`_ library is required IF
|
- The `praatIO <https://github.com/timmahrt/praatIO>`_ library is required IF
|
||||||
you want to use the textgrid functionality. It is not required
|
you want to use the textgrid functionality. It is not required
|
||||||
for normal use.
|
for normal use.
|
||||||
@@ -58,10 +83,12 @@ Requirements
|
|||||||
Installation
|
Installation
|
||||||
================
|
================
|
||||||
|
|
||||||
From a command-line shell, navigate to the directory this is located in
|
If you on Windows, you can use the installer found here (check that it is up to date though)
|
||||||
and type::
|
`Windows installer <http://www.timmahrt.com/python_installers>`_
|
||||||
|
|
||||||
python setup.py install
|
Otherwise, to manually install, after downloading the source from github, from a command-line shell, navigate to the directory containing setup.py and type::
|
||||||
|
|
||||||
|
python setup.py install
|
||||||
|
|
||||||
If python is not in your path, you'll need to enter the full path e.g.::
|
If python is not in your path, you'll need to enter the full path e.g.::
|
||||||
|
|
||||||
@@ -93,5 +120,26 @@ and another::
|
|||||||
>> [["''"], ['n', '@'], ['th', 'r']]
|
>> [["''"], ['n', '@'], ['th', 'r']]
|
||||||
|
|
||||||
|
|
||||||
Please see \\test for example usage
|
Please see \\examples for example usage
|
||||||
|
|
||||||
|
|
||||||
|
Citing pysle
|
||||||
|
===============
|
||||||
|
|
||||||
|
Pysle is general purpose coding and doesn't need to be cited
|
||||||
|
(you should cite the
|
||||||
|
`ISLEX project <http://www.isle.illinois.edu/sst/data/dict/islex/index.shtml>`_
|
||||||
|
instead) but if you would like to, it can be cited like so:
|
||||||
|
|
||||||
|
Tim Mahrt. Pysle. https://github.com/timmahrt/pysle, 2016.
|
||||||
|
|
||||||
|
|
||||||
|
Acknowledgements
|
||||||
|
================
|
||||||
|
|
||||||
|
Development of Pysle was possible thanks to NSF grant **IIS 07-03624**
|
||||||
|
to Jennifer Cole and Mark Hasegawa-Johnson, NSF grant **BCS 12-51343**
|
||||||
|
to Jennifer Cole, José Hualde, and Caroline Smith, and
|
||||||
|
to the A*MIDEX project (n° **ANR-11-IDEX-0001-02**) to James Sneed German
|
||||||
|
funded by the Investissements d’Avenir French Government program, managed
|
||||||
|
by the French National Research Agency (ANR).
|
||||||
|
|||||||
+12
-11
@@ -69,21 +69,22 @@ def _parsePronunciation(pronunciationStr):
|
|||||||
secondary stress locations
|
secondary stress locations
|
||||||
'''
|
'''
|
||||||
syllableTxt = pronunciationStr.split("#")[1].strip()
|
syllableTxt = pronunciationStr.split("#")[1].strip()
|
||||||
syllableList = [x for x in syllableTxt.split(' . ')]
|
syllableList = [x.split() for x in syllableTxt.split(' . ')]
|
||||||
|
|
||||||
# Find stress
|
# Find stress
|
||||||
stressList = []
|
stressedSyllableList = []
|
||||||
|
stressedPhoneList = []
|
||||||
for i, syllable in enumerate(syllableList):
|
for i, syllable in enumerate(syllableList):
|
||||||
# Primary stress
|
for j, phone in enumerate(syllable):
|
||||||
if "'" in syllable:
|
if "'" in phone:
|
||||||
stressList.insert(0, i)
|
stressedSyllableList.insert(0, i)
|
||||||
# Secondary stress
|
stressedPhoneList.insert(0, j)
|
||||||
elif '"' in syllable:
|
break
|
||||||
stressList.append(i)
|
elif '"' in phone:
|
||||||
|
stressedSyllableList.insert(i)
|
||||||
|
stressedPhoneList.insert(j)
|
||||||
|
|
||||||
syllableList = [x.split(" ") for x in syllableList]
|
return syllableList, stressedSyllableList, stressedPhoneList
|
||||||
|
|
||||||
return syllableList, stressList
|
|
||||||
|
|
||||||
|
|
||||||
def getNumPhones(isleDict, label, maxFlag):
|
def getNumPhones(isleDict, label, maxFlag):
|
||||||
|
|||||||
+36
-19
@@ -11,7 +11,7 @@ class OptionalFeatureError(ImportError):
|
|||||||
return "ERROR: You must have praatio installed to use pysle.praatTools"
|
return "ERROR: You must have praatio installed to use pysle.praatTools"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import praatio
|
from praatio import tgio
|
||||||
except ImportError:
|
except ImportError:
|
||||||
raise OptionalFeatureError()
|
raise OptionalFeatureError()
|
||||||
|
|
||||||
@@ -39,7 +39,8 @@ def syllabifyTextgrid(isleDict, tg, wordTierName, phoneTierName,
|
|||||||
skipLabelList = []
|
skipLabelList = []
|
||||||
|
|
||||||
syllableEntryList = []
|
syllableEntryList = []
|
||||||
tonicEntryList = []
|
tonicSEntryList = []
|
||||||
|
tonicPEntryList = []
|
||||||
for start, stop, word in wordTier.entryList:
|
for start, stop, word in wordTier.entryList:
|
||||||
|
|
||||||
if word in skipLabelList:
|
if word in skipLabelList:
|
||||||
@@ -63,8 +64,20 @@ def syllabifyTextgrid(isleDict, tg, wordTierName, phoneTierName,
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
syllableList = returnList[1]
|
syllableList = returnList[1]
|
||||||
stressIndexList = returnList[3]
|
stressedSyllableIndexList = returnList[3]
|
||||||
|
stressedPhoneIndexList = returnList[4]
|
||||||
|
flattenedPhoneIndexList = returnList[5]
|
||||||
|
|
||||||
|
try:
|
||||||
|
stressI = stressedSyllableIndexList[0]
|
||||||
|
stressJ = stressedPhoneIndexList[0]
|
||||||
|
except IndexError:
|
||||||
|
stressI = None # Function word probably
|
||||||
|
stressJ = None #
|
||||||
|
|
||||||
|
if stressI is not None:
|
||||||
|
syllableList[stressI][stressJ] += "'"
|
||||||
|
|
||||||
i = 0
|
i = 0
|
||||||
# print(syllableList)
|
# print(syllableList)
|
||||||
for k, syllable in enumerate(syllableList):
|
for k, syllable in enumerate(syllableList):
|
||||||
@@ -84,24 +97,28 @@ def syllabifyTextgrid(isleDict, tg, wordTierName, phoneTierName,
|
|||||||
|
|
||||||
syllableEntryList.append((syllableStart, syllableEnd, label))
|
syllableEntryList.append((syllableStart, syllableEnd, label))
|
||||||
|
|
||||||
# Create the tonic tier entry
|
# Create the tonic syllable tier entry
|
||||||
try:
|
if k == stressI:
|
||||||
stressIndex = stressIndexList[0]
|
tonicSEntryList.append((syllableStart, syllableEnd, 'T'))
|
||||||
except IndexError:
|
|
||||||
stressIndex = None # Function word probably
|
# Create the tonic phone tier entry
|
||||||
|
if k == stressI:
|
||||||
tonicLabel = ''
|
syllablePhoneTier = phoneTier.crop(syllableStart, syllableEnd,
|
||||||
if k == stressIndex:
|
True, False)[0]
|
||||||
tonicLabel = 'T'
|
|
||||||
|
phoneList = [entry for entry in syllablePhoneTier.entryList
|
||||||
tonicEntryList.append((syllableStart, syllableEnd, tonicLabel))
|
if entry[2] != '']
|
||||||
|
phoneStart, phoneEnd = phoneList[stressJ][:2]
|
||||||
|
tonicPEntryList.append((phoneStart, phoneEnd, 'T'))
|
||||||
|
|
||||||
# Create a textgrid with the two syllable-level tiers
|
# Create a textgrid with the two syllable-level tiers
|
||||||
syllableTier = praatio.IntervalTier("syllable", syllableEntryList)
|
syllableTier = tgio.IntervalTier("syllable", syllableEntryList)
|
||||||
tonicTier = praatio.IntervalTier('tonic', tonicEntryList)
|
tonicSTier = tgio.IntervalTier('tonicSyllable', tonicSEntryList)
|
||||||
|
tonicPTier = tgio.IntervalTier('tonicVowel', tonicPEntryList)
|
||||||
|
|
||||||
syllableTG = praatio.Textgrid()
|
syllableTG = tgio.Textgrid()
|
||||||
syllableTG.addTier(syllableTier)
|
syllableTG.addTier(syllableTier)
|
||||||
syllableTG.addTier(tonicTier)
|
syllableTG.addTier(tonicSTier)
|
||||||
|
syllableTG.addTier(tonicPTier)
|
||||||
|
|
||||||
return syllableTG
|
return syllableTG
|
||||||
|
|||||||
@@ -243,16 +243,16 @@ def alignPronunciations(pronI, pronA):
|
|||||||
|
|
||||||
# Fill in any blanks such that the sequential items have the same
|
# Fill in any blanks such that the sequential items have the same
|
||||||
# index and the two strings are the same length
|
# index and the two strings are the same length
|
||||||
for x in xrange(len(sequenceIndexListA)):
|
for x in range(len(sequenceIndexListA)):
|
||||||
indexA = sequenceIndexListA[x]
|
indexA = sequenceIndexListA[x]
|
||||||
indexI = sequenceIndexListI[x]
|
indexI = sequenceIndexListI[x]
|
||||||
if indexA < indexI:
|
if indexA < indexI:
|
||||||
for x in xrange(indexI - indexA):
|
for x in range(indexI - indexA):
|
||||||
pronA.insert(indexA, "''")
|
pronA.insert(indexA, "''")
|
||||||
sequenceIndexListA = [val + indexI - indexA
|
sequenceIndexListA = [val + indexI - indexA
|
||||||
for val in sequenceIndexListA]
|
for val in sequenceIndexListA]
|
||||||
elif indexA > indexI:
|
elif indexA > indexI:
|
||||||
for x in xrange(indexA - indexI):
|
for x in range(indexA - indexI):
|
||||||
pronI.insert(indexI, "''")
|
pronI.insert(indexI, "''")
|
||||||
sequenceIndexListI = [val + indexA - indexI
|
sequenceIndexListI = [val + indexA - indexI
|
||||||
for val in sequenceIndexListI]
|
for val in sequenceIndexListI]
|
||||||
@@ -275,13 +275,25 @@ def findBestSyllabification(isleDict, wordText, actualPronunciationList):
|
|||||||
alignedPhoneList = alignedAPronList[bestIndex]
|
alignedPhoneList = alignedAPronList[bestIndex]
|
||||||
alignedSyllables = alignedSyllableList[bestIndex]
|
alignedSyllables = alignedSyllableList[bestIndex]
|
||||||
syllabification = isleWordList[bestIndex][0]
|
syllabification = isleWordList[bestIndex][0]
|
||||||
stressedIndex = isleWordList[bestIndex][1]
|
stressedSyllableIndexList = isleWordList[bestIndex][1]
|
||||||
|
stressedPhoneIndexList = isleWordList[bestIndex][2]
|
||||||
|
|
||||||
stressedSyllable, syllableList = _syllabifyPhones(alignedPhoneList,
|
stressedSyllable, syllableList = _syllabifyPhones(alignedPhoneList,
|
||||||
alignedSyllables,
|
alignedSyllables,
|
||||||
stressedIndex)
|
stressedSyllableIndexList)
|
||||||
|
|
||||||
return stressedSyllable, syllableList, syllabification, stressedIndex
|
# Count the index of the stressed phones, if the stress list has
|
||||||
|
# become flattened (no syllable information)
|
||||||
|
flattenedStressIndexList = []
|
||||||
|
for i, j in zip(stressedSyllableIndexList, stressedPhoneIndexList):
|
||||||
|
k = j
|
||||||
|
for l in range(i):
|
||||||
|
k += len(syllableList[l])
|
||||||
|
flattenedStressIndexList.append(k)
|
||||||
|
|
||||||
|
return (stressedSyllable, syllableList, syllabification,
|
||||||
|
stressedSyllableIndexList, stressedPhoneIndexList,
|
||||||
|
flattenedStressIndexList)
|
||||||
|
|
||||||
|
|
||||||
def findClosestPronunciation(isleDict, wordText, aPron):
|
def findClosestPronunciation(isleDict, wordText, aPron):
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ Created on Oct 15, 2014
|
|||||||
'''
|
'''
|
||||||
from distutils.core import setup
|
from distutils.core import setup
|
||||||
setup(name='pysle',
|
setup(name='pysle',
|
||||||
version='1.0.0',
|
version='1.3.0',
|
||||||
author='Tim Mahrt',
|
author='Tim Mahrt',
|
||||||
author_email='timmahrt@gmail.com',
|
author_email='timmahrt@gmail.com',
|
||||||
package_dir={'pysle':'pysle'},
|
package_dir={'pysle':'pysle'},
|
||||||
@@ -13,4 +13,4 @@ setup(name='pysle',
|
|||||||
license='LICENSE',
|
license='LICENSE',
|
||||||
long_description=open('README.rst', 'r').read(),
|
long_description=open('README.rst', 'r').read(),
|
||||||
# install_requires=[], # No requirements! # requires 'from setuptools import setup'
|
# install_requires=[], # No requirements! # requires 'from setuptools import setup'
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -12,14 +12,14 @@ This snippet shows you how to use this function.
|
|||||||
|
|
||||||
from os.path import join
|
from os.path import join
|
||||||
|
|
||||||
import praatio
|
from praatio import tgio
|
||||||
from pysle import isletool
|
from pysle import isletool
|
||||||
from pysle import praattools
|
from pysle import praattools
|
||||||
|
|
||||||
path = join('.', 'files')
|
path = join('.', 'files')
|
||||||
path = "/Users/tmahrt/Dropbox/workspace/pysle/test/files"
|
path = "/Users/tmahrt/Dropbox/workspace/pysle/test/files"
|
||||||
|
|
||||||
tg = praatio.openTextGrid(join(path, "pumpkins.TextGrid"))
|
tg = tgio.openTextGrid(join(path, "pumpkins.TextGrid"))
|
||||||
|
|
||||||
# Needs the full path to the file
|
# Needs the full path to the file
|
||||||
islevPath = '/Users/tmahrt/Dropbox/workspace/pysle/test/islev2.txt'
|
islevPath = '/Users/tmahrt/Dropbox/workspace/pysle/test/islev2.txt'
|
||||||
@@ -29,7 +29,8 @@ isleDict = isletool.LexicalTool(islevPath)
|
|||||||
syllableTG = praattools.syllabifyTextgrid(isleDict, tg, "word", "phone",
|
syllableTG = praattools.syllabifyTextgrid(isleDict, tg, "word", "phone",
|
||||||
skipLabelList=["",])
|
skipLabelList=["",])
|
||||||
tg.addTier(syllableTG.tierDict["syllable"])
|
tg.addTier(syllableTG.tierDict["syllable"])
|
||||||
tg.addTier(syllableTG.tierDict["tonic"])
|
tg.addTier(syllableTG.tierDict["tonicSyllable"])
|
||||||
|
tg.addTier(syllableTG.tierDict["tonicVowel"])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user