Back to the Emu home page

Emu and BAS Partitur

I've been experimenting with the BAS Partitur label file format, trying to understand it and trying to get Emu to read it. Working from the information at BAS and using some example files obtained from

My interpretation of this format is that it is a simple hierarchy centered around the KAN or Canonical Pronunciation level or tier. Other levels may be symbolically linked to KAN via index numbers. The number of allowed levels is small and is controlled by the Partitur standard, so arbitrary level names are not allowed. I'm not entirely clear on the exact allowed relationship between levels or whether there are any restrictions -- such as disallowing many-to-many links between certain levels.

Since all levels are linked to KAN this isn't so much a hierarchy as a collection of interlinked hierarchies. Emu is quite happy with this and the template file I've put together has all levels being children of the KAN level except for DAS (Dialog Act Segmentation) which clearly dominates KAN. In some cases the links from KAN to its children should perhaps be many-to-many but I've not come across cases where this is needed yet.

I've written an Emu template file which I think captures the relationships between levels, it is included at the end of this page

I then wrote a tcl script which parsed the Partitur label file and built an Emu hierarchy. This was fairly simple given the very clean Partitur file format and the simple relationships between levels.

One problem with this simplistic script is the treatment of times at the phonetic levels. Partitur uses sample numbers and these would need to be translated into millisecond times for Emu. This should be simple as the label file includes the sample rate, presumably of the primary acoustic signal.

The sample files that I have looked at haven't contained any WOR level labels, I would imagine that these should come between the KAN and the MAU/PHO/SAP levels but in the Partitur format they are all just linked to the KAN level.

I have assumed that the labels in the Partitur file occur in order although there seems to be no specification that this is correct. In many cases the links to the KAN level give an ordering but in some cases where the index is -1 we must assume that the segment order is important.

Having converted the label files into an Emu format, we can perform queries like

[MAU=m -> MAU=U]
to find sequences of m and U phonemes. If suitable categories were defined in the template file (vial legal lines), we could say
[MAU=nasal -> MAU=vowel]
to find sequences of nasal phonemes followed by vowels. Hierarchical queries would only be able to relate to the KAN/ORT level, so we could find all word final vowels as:

If you are interested, I made a jpeg image from one of the hierarchies built with the script. The image shows the DAS, KAN and MAU levels. The image corresponds to the utterance g102a002, from the VerbMobil database mentioned above. The original label file can be found here.


One reason for attempting this exercise was to show that Emu was able to represent the hierarchies defined by the Partitur format. As far as I understand these, I think that Emu copes well. This kind of script is one solution to using `foreign' databases with Emu, but in the longer term it would be desirable for Emu to read as much information from the label file as possible natively. I feel that there is a place for Emu's own hierarchical label file format even with label file formats like Partitur since Emu's format is optimised for speed of reading. The mode of operation then with Partitur databases would be to run a script which builds a hierarchical label file, perhaps augmenting the Partitur structure with other levels such as syllabification. The information about segment times would then be gleaned from the Partitur format file (or optionally written to seperate label files), while hierarchical structure was taken from the Emu format file.

There are many label file formats out there and I think that in the long term Emu should be made to read as many of them as possible (likewise for data file formats). Adding C++ code for a reading new file format is fairly simple as long as the format fits within Emu's current idea of what a label file is. There maybe some strange label file formats which require modifications to Emu's model, and I'm keen to make those changes to make Emu a useful general purpose speech database tool.

Any comments are welcome, please send them to the emu mailing list or to me personally at

Partitur Emu Template File

! Emu template for BAS Partitur label file import
! an attempt to mirror the Partitur hierarchy in Emu

!DAS: Dialog act segmentation, dominates KAN
level DAS

!KAN: Canonical Pronunciation, this is the reference tier
level KAN	DAS
!TRL: Verbmobil Transliteration - VM I, child of KAN
level TRL	KAN
!TR2: Verbmobil Transliteration - VM II, also child of KAN, no relation to TRL
level TR2	KAN
!SUP: Superimposed speech, not sure how to deal with this
level SUP       KAN

!WOR: Word segmentation, timed, child of KAN, may have missing words,
!     insertions or replacements relative to KAN, indicated by trailing -, 
!     leading - or - between words (bar- -foo foo-bar)
!     these are the words which actually appear, so phonetic segmentation
!     should probably hang off these, but then this level isn't mandatory
!     so it probably depends on the individual database
level WOR	KAN

!     Phonetic segmentations, should they hang off of KAN or WOR (or TRL/TR2)?
!PHO: Broad phonetic segmentation - PhonDat 
level PHO	KAN
!SAP: Broad phonetic segmentation - Verbmobil
level SAP	KAN
!MAU: Automatic broad phonetic segmentation by MAUS
level MAU	KAN

!ORT: Orthography, 1:1 correspondence to KAN, so it's a label
label KAN	ORT

! we'll generate lab files for these levels when we import the utterances
labfile	PHO :extension pho :time-factor 1000
labfile SAP :extension sap :time-factor 1000
labfile MAU :extension mau :time-factor 1000

! a path for partitur files, should be used by the import script
path	par	/home/dbase/foreign/VM/*
path	hlb,pho,sap,mau	/home/recog/steve/partitur/*

! no tracks, will emu cope!

set PrimaryExtension hlb

Emu Script to import Partitur Files

# The next line is executed by /bin/sh, but not tcl \
exec /usr/local/bin/emush $0 ${1+"$@"}

# import a partitur format label file into Emu -- ie build 
# ESPS label files and an hlb file from a partitur format file

# procedures...

# clear all segments from a level 

proc clear_level {level} {
    hier delete segments [hier segments $level]

# create a level below KAN

proc create_partitur_sub_level {level} {
    global partitur KANsegs

    clear_level $level

    foreach s $partitur($level) {
	set index [lindex $s 0]
	set label [join [lrange $s 1 end] "_"]
	set newseg [hier append $level $label]
	if {$index != -1} {
	    if [info exists KANsegs($index)] {
		hier seginfo $newseg parents $level $KANsegs($index)
	    } else {
		puts "no segment corresopnds to $level index $index, label $label"

proc create_partitur_timed_level {level} {
    global partitur KANsegs

    clear_level $level

    foreach s $partitur($level) {
	set startsamp [lindex $s 0]
	set nsamps [lindex $s 1]
	set index [lindex $s 2]
	set label [lindex $s 3]

	set newseg [hier append $level $label]
	# set times for the new segment, 
	# this is wrong as it is in sample numbers

	hier seginfo $newseg times $startsamp [expr $startsamp+$nsamps] 
	if {$index != -1} {
	    if [info exists KANsegs($index)] {
		hier seginfo $newseg parents KAN $KANsegs($index)
	    } else {
		puts "no segment corresopnds to $level index $index, label $label"

proc create_partitur_super_level {level} {
    global partitur KANsegs

    hier delete segments [hier segments $level]
    foreach s $partitur(DAS) {
	# in this case the index can be more than one number

	set index [split [lindex $s 0] ,]
	set label [join [lrange $s 1 end] _]

	set newseg [hier append DAS $label]
	# get the children at the KAN level

	set children {}
	foreach c $index {

	    if [info exists KANsegs($c)] {
		lappend children $KANsegs($c)
	hier seginfo $newseg children KAN $children

## Main program...

if {[llength $argv] != 1} {
    puts "Usage: import_partitur uttname"

emutemplate templ partitur

set uttname [lindex $argv 0]
# get the partitur file name via the template

set partfile [templ resolve $uttname par]

# read the label file lines and store them in the partitur array 

set handle [open $partfile r]
while {[gets $handle line] > 0} {
    # each line must begin with a three letter key

    set key [string range $line 0 2]
    # now treat line as a list and save all but the first element

    lappend partitur($key) [lrange $line 1 end]

# create a new hierarchy 

templ hierarchy hier $uttname

# create the KAN level segments, this is the reference level
# remember which KAN reference ID corresponds to which segment number

hier delete segments [hier segments KAN]
foreach s $partitur(KAN) {
    set index [lindex $s 0]
    set label [lindex $s 1]
    set segno [hier append KAN $label]
    set KANsegs($index) $segno

# add ORT labels to KAN segments if provided

foreach s $partitur(ORT) {
    set index [lindex $s 0]
    set label [lindex $s 1]
    if [info exists KANsegs($index)] {
	hier seginfo $KANsegs($index) label ORT $label
    } else {
	puts "no segment corresopnds to ORT index $index, label $label"

# create various other levels, linked to KAN

create_partitur_timed_level MAU
create_partitur_timed_level SAP
create_partitur_sub_level TRL
create_partitur_sub_level TR2

create_partitur_super_level DAS

# write hierarchy and ESPS format label files

hier writelabels
hier write $uttname

Steve Cassidy
Last modified: Wed Jun 24 15:43:19 EST 1998