Skip to content

Recognition quality and languages

What Flat's Optical Music Recognition reads well, what it does with lyrics, and what to do when a result is not what you expected.

What OMR reads

What kind of sheet music works well?

OMR works best on clean, printed sheet music in standard notation: engraved scores, good scans, and sharp photos, from single instruments through grand-staff piano to full orchestral scores. Handwritten music and guitar tablature are not supported. As a rule of thumb, if a page is hard for a person to read, it is hard for Flat to read.

The help center is the source of truth for what is recognized, and it is kept current as the engine improves:

Does score length or complexity affect quality?

No. The processing pipeline is the same regardless of how long a score is, and there is no score splitting that would degrade longer pieces. If quality drops partway through a long score, that is a notation or scan issue on those pages, not a length effect. It is worth reporting.

How do I find out about recognition improvements?

The OMR changelog covers ML model updates and other significant recognition changes. It does not list every bug fix.

For changes to the API surface itself, endpoints, fields, and behavior, see the REST API changelog.

Languages and lyrics

Which languages are supported for lyrics?

The supported set is returned as locales (BCP 47 codes) and localesDetails (the same codes with English display names, ready to drop into a language picker) by GET /omr/capabilities, which needs no authentication.

65 languages are currently supported:

Afrikaans (af), Albanian (sq), Arabic (ar), Azerbaijani (az), Bengali (bn), Bosnian (bs), Bulgarian (bg), Chinese (Hong Kong) (zh-HK), Chinese (Simplified) (zh-Hans), Chinese (Taiwan) (zh-TW), Croatian (hr), Czech (cs), Danish (da), Dutch (nl), English (UK) (en-GB), English (US) (en), Estonian (et), Filipino (fil), Finnish (fi), French (fr), French (Canada) (fr-CA), German (de), Greek (el), Hindi (hi), Hungarian (hu), Icelandic (is), Indonesian (id), Irish (ga), Italian (it), Japanese (ja), Japanese (Hiragana) (ja-HIRA), Kannada (kn), Korean (ko), Kurdish (ku), Latin (la), Latvian (lv), Lithuanian (lt), Malay (ms), Maltese (mt), Māori (mi), Marathi (mr), Nepali (ne), Norwegian (Bokmål) (nb), Occitan (oc), Persian (fa), Polish (pl), Portuguese (pt), Portuguese (BR) (pt-BR), Romanian (ro), Russian (ru), Serbian (sr), Slovak (sk), Slovenian (sl), Spanish (es), Swahili (sw), Swedish (sv), Tamil (ta), Telugu (te), Thai (th), Turkish (tr), Ukrainian (uk), Urdu (ur), Uzbek (uz), Vietnamese (vi), Welsh (cy).

New languages are added over time, so build your picker from localesDetails rather than hardcoding a list.

What do locales and mainLanguage actually do?

They tell the recognition pipeline which language to read lyrics and text in. They do not affect the notation itself.

They are not just a hint. Flat runs different OCR models depending on the languages you declare, and can run several models over the same file to get the best reading, then links the recognized text back to the note positions. So locales genuinely changes which models see your pages, which is why an accurate value is worth setting and why a wrong one degrades the lyrics.

  • locales is set when you create the job, as an array of BCP 47 codes. Pass the languages the score is likely to use. Defaulting to the user's own locale, when it appears in locales, is a good starting point.
  • mainLanguage is set when you submit the details step and overrides the job locale for the whole score. It is the natural place to let a user correct the language after seeing the detected title.

What happens if the lyrics are in an unsupported language?

The job succeeds and the lyrics come back wrong, rather than failing with an error. Characters and diacritics can be mangled, and there is no validation warning to tell you why.

So check that the language you need appears in locales before you build on it. If it is missing, email developers@flat.io: languages get added on request, and several in the list above arrived that way.

When a result is wrong

A conversion came back inaccurate. What do I do?

Email developers@flat.io with the job ID (the id from POST /omr/jobs, or the task id for the auto simple import). That is the fastest thing to give us: it lets us pull up the exact run, its inputs, and its internal quality report. Attaching the source file and a description of what is wrong, ideally with measure numbers, helps too.

Concrete examples are far more useful than a general report, and they are how the engine gets better.

What happens next:

  1. We investigate whether the example is an isolated case or a recurring limitation in the recognition or score-assembly pipeline.
  2. Recurring limitations are fixed in the product.
  3. Once an improvement ships, we can reprocess affected conversions.

There is no automatic credit refund for a conversion that completes but is inaccurate. Credits are reverted for jobs that fail, see Do failed jobs consume credits? If you are running a large batch, tell us before you start rather than after.

How do I know which OMR ML model version produced a result?

The version of the OMR machine-learning model that read your pages is embedded in the MusicXML output. Record it alongside the result and you can tell later which of your conversions predate a given improvement, which is exactly what you need when deciding what to reprocess.

Is there a confidence score for a whole job?

Not for the job as a whole. What you do get is per-part confidence during the optional details review step: each detected instrument carries a resolvedConfidence of high, medium, or low, which is what the Flat and Opuscan apps use to decide what to put in front of a user for confirmation. Rendering that step is the most effective quality control you can add to an integration.

Copyright © Tutteo Limited