<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lova</title>
    <description>The latest articles on DEV Community by Lova (@kruhlova).</description>
    <link>https://dev.to/kruhlova</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4131877%2F055c8739-127b-4e51-991c-6cd931818694.png</url>
      <title>DEV Community: Lova</title>
      <link>https://dev.to/kruhlova</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kruhlova"/>
    <language>en</language>
    <item>
      <title>Sound Analysis Has No cat_hiss Label</title>
      <dc:creator>Lova</dc:creator>
      <pubDate>Fri, 18 Sep 2026 17:24:50 +0000</pubDate>
      <link>https://dev.to/kruhlova/sound-analysis-has-no-cathiss-label-974</link>
      <guid>https://dev.to/kruhlova/sound-analysis-has-no-cathiss-label-974</guid>
      <description>&lt;h2&gt;
  
  
  Apple Sound Analysis can hear a meow. It cannot name a hiss
&lt;/h2&gt;

&lt;p&gt;Apple's built-in Sound Analysis model can label &lt;code&gt;cat_meow&lt;/code&gt; and &lt;code&gt;cat_purr&lt;/code&gt;. It has no &lt;code&gt;cat_hiss&lt;/code&gt; class. Point a mic at a real hiss and you often get silence, a generic &lt;code&gt;cat&lt;/code&gt; hit, or — worse — &lt;code&gt;snake_hiss&lt;/code&gt;. Energy metering only proves something crossed a loudness line. Neither path answers why the cat hissed, and neither path is a finished pet feature.&lt;/p&gt;

&lt;p&gt;This piece is for the iOS engineer who already knows they will call &lt;code&gt;SNClassifySoundRequest&lt;/code&gt;, not for the owner Googling "cat hissing" after a carrier scare. Search intent on that phrase is domain research. Your shipping problem is narrower: the public label list stops at meow and purr.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who hits this wall
&lt;/h2&gt;

&lt;p&gt;You are building a pet-audio feature. You need proof, on device, that Apple's free classifier does not cover the sound you care about. A custom Core ML model can invent classes. The stock Sound Analysis path sits one step before that decision — and that is where the gap lives.&lt;/p&gt;

&lt;p&gt;If your product brief says "detect cat sounds," treat hiss as out of scope for &lt;code&gt;.version1&lt;/code&gt; until you have printed the live class list yourself. Do not ship UI that assumes a missing identifier will appear under a different name.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prove the gap before you build a pipeline
&lt;/h2&gt;

&lt;p&gt;You do not need a production recorder to learn the hard limit. You need one finished audio file of a real hiss (or a short take you already recorded) and a read of &lt;code&gt;knownClassifications&lt;/code&gt; on the OS you ship.&lt;/p&gt;

&lt;p&gt;Minimal check — not a day-one product scaffold:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;SoundAnalysis&lt;/span&gt;

&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;proveCatHissGap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throws&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="kt"&gt;SNClassifySoundRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;classifierIdentifier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;version1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Gap-proof at runtime — do not hardcode a blog dump:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"has cat_hiss?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;knownClassifications&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cat_hiss"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"has snake_hiss?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;knownClassifications&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"snake_hiss"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"has cat_meow?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;knownClassifications&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cat_meow"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"has cat_purr?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;knownClassifications&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cat_purr"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;analyzer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="kt"&gt;SNAudioFileAnalyzer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;observer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;LabelProbe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="n"&gt;analyzer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;withObserver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;analyzer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;analyze&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;observer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;forEach&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"%.2f"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;LabelProbe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;NSObject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;SNResultsObserving&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Double&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;SNRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;didProduce&lt;/span&gt; &lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;SNResult&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;guard&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="k"&gt;as?&lt;/span&gt; &lt;span class="kt"&gt;SNClassificationResult&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;contentsOf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;classifications&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;identifier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;confidence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;SNRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;didFailWithError&lt;/span&gt; &lt;span class="nv"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SoundAnalysis error:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;localizedDescription&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is enough to falsify the assumption. You are not copying a production AAC gate, a Documents move race, or a permission dance into a tutorial that pretends to be the feature. Those belong in your app's recorder once you decide classification is still worth calling.&lt;/p&gt;

&lt;p&gt;What the printout should show on &lt;code&gt;.version1&lt;/code&gt;: &lt;code&gt;cat_hiss&lt;/code&gt; is absent; &lt;code&gt;snake_hiss&lt;/code&gt; is present; &lt;code&gt;cat_meow&lt;/code&gt; / &lt;code&gt;cat_purr&lt;/code&gt; are present. The animal block jumps from domestic cat labels into other species. There is no &lt;code&gt;cat_spit&lt;/code&gt; and no &lt;code&gt;cat_growl&lt;/code&gt; in the public list either.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a real hiss tends to return
&lt;/h2&gt;

&lt;p&gt;After a few live takes, patterns repeat even when your recorder code differs from mine:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Clip&lt;/th&gt;
&lt;th&gt;Typical top label&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Close meow&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;cat_meow&lt;/code&gt; with usable confidence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Steady purr&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cat_purr&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Angry hiss, farther away&lt;/td&gt;
&lt;td&gt;silence / weak generic &lt;code&gt;cat&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Angry hiss, close mic&lt;/td&gt;
&lt;td&gt;often &lt;code&gt;snake_hiss&lt;/code&gt; or junk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Non-cat broadband noise&lt;/td&gt;
&lt;td&gt;trips "something happened," not "cat"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Apple documents that you should read confidence with &lt;code&gt;classification(forIdentifier:)&lt;/code&gt; and pick your own threshold (WWDC21 samples use &lt;strong&gt;0.5&lt;/strong&gt;). Raising the bar to &lt;strong&gt;0.7&lt;/strong&gt; cleans false positives. It does not invent a missing class.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why &lt;code&gt;snake_hiss&lt;/code&gt; shows up
&lt;/h3&gt;

&lt;p&gt;Broadband turbulent airflow looks similar across species to a general audio model. Confidence of &lt;strong&gt;0.3–0.6&lt;/strong&gt; on &lt;code&gt;snake_hiss&lt;/code&gt; for a cat is a category collision, not a biology claim. Drop any owner-facing string that would surface that identifier. Logging it in debug is fine; shipping it in a toast is not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Loudness is not a species label
&lt;/h2&gt;

&lt;p&gt;If you meter while recording, you only learn that energy crossed a tripwire. A common on-device habit is polling &lt;code&gt;averagePower&lt;/code&gt; on the order of a few times per second and treating values above roughly &lt;strong&gt;−40 dBFS&lt;/strong&gt; as "had sound." That filter saves empty files and battery. It does not tell you the animal, the affect, or the missing class name.&lt;/p&gt;

&lt;p&gt;Tune only after you have lived with the room: &lt;strong&gt;−35&lt;/strong&gt; is stricter and misses soft hisses; &lt;strong&gt;−50&lt;/strong&gt; grabs fridge hum. Log a kitchen baseline before you treat any threshold as sacred. Permission denied still fails earlier than any of this — Settings → Privacy &amp;amp; Security → Microphone for your target — and &lt;code&gt;NSMicrophoneUsageDescription&lt;/code&gt; must exist or the first record call is dead on arrival. Deployment target for the Sound Analysis path you care about here is &lt;strong&gt;iOS 16+&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;None of that metering detail is the product. It is hygiene around a classifier that still cannot say &lt;code&gt;cat_hiss&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest limit of the stock path
&lt;/h2&gt;

&lt;p&gt;When the file path works, you own two things: a clip on disk and a string label (or a ranked list of them). You still do not know whether the hiss meant pain, a new dog in the hallway, or "stop petting." Behaviorists read hissing as a distance-increasing warning — fear or stress more often than pure attack — but that reading needs eyes on ears, tail, and pupils, not a 44.1 kHz buffer. Sound Analysis will not write that sentence.&lt;/p&gt;

&lt;p&gt;Shipping a custom Core ML sound model is the usual next &lt;em&gt;engineering&lt;/em&gt; move if your requirement is a dedicated &lt;code&gt;cat_hiss&lt;/code&gt; class under your own control. Budget &lt;strong&gt;weeks&lt;/strong&gt;, not an afternoon: labeled hiss clips, background rejection, on-device size, and App Review scrutiny if copy drifts into animal-health claims. Most teams stop at "we detected a loud event" and leave meaning somewhere else.&lt;/p&gt;

&lt;p&gt;That "somewhere else" is the real product boundary. Classification ends at a label. Owner-facing sense — a short line that treats the moment as playable, not clinical — is a separate experience layer. It is not a memo app plus a veterinary article tab, and it is not a weekend DIY classifier with a confidence slider.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the stock path ends — and what sits next to it
&lt;/h2&gt;

&lt;p&gt;If your job is to prove Apple's free model cannot name a cat hiss, you are done when &lt;code&gt;knownClassifications.contains("cat_hiss")&lt;/code&gt; prints &lt;code&gt;false&lt;/code&gt; and a few live takes show silence, weak &lt;code&gt;cat&lt;/code&gt;, or &lt;code&gt;snake_hiss&lt;/code&gt;. Do not keep pasting recorder + analyzer + UI copy until the tutorial has rebuilt a pet app.&lt;/p&gt;

&lt;p&gt;If your job is to give a cat owner something after the waveform, you leave the classifier at the edge and hand the moment to a layer that was built for that handoff. On iPhone, &lt;a href="https://mycattranslator.com/blog/cat-hissing" rel="noopener noreferrer"&gt;Cat Translator&lt;/a&gt; is that adjacent edge: record the hiss, get a playful line back, without training your own Core ML sound model and without turning the screen into a clinical aggression guide. The classifier problem stays a classifier problem. The meaning problem stays an experience problem.&lt;/p&gt;

&lt;p&gt;That split is the honest shipping story. Sound Analysis gives you a label when a class exists. For hiss, the class does not exist. Pretending metering + &lt;code&gt;.version1&lt;/code&gt; closes the owner loop is how products ship &lt;code&gt;snake_hiss&lt;/code&gt; into a living room.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checklist before you call the investigation done
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Live &lt;code&gt;knownClassifications&lt;/code&gt; printed on the OS you ship&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;cat_hiss&lt;/code&gt; confirmed absent; &lt;code&gt;snake_hiss&lt;/code&gt; / &lt;code&gt;cat_meow&lt;/code&gt; / &lt;code&gt;cat_purr&lt;/code&gt; noted&lt;/li&gt;
&lt;li&gt;[ ] At least a handful of real hiss takes logged with top labels&lt;/li&gt;
&lt;li&gt;[ ] No owner-facing UI that displays &lt;code&gt;snake_hiss&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] No health claims tied to a Sound Analysis string&lt;/li&gt;
&lt;li&gt;[ ] Decision recorded: stay on stock labels, train custom audio ML, or hand meaning to a separate experience layer&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does Sound Analysis support cat hissing in a later classifier version?
&lt;/h3&gt;

&lt;p&gt;As of &lt;code&gt;SNClassifierIdentifier.version1&lt;/code&gt; (the built-in identifier Apple documents for &lt;code&gt;SNClassifySoundRequest&lt;/code&gt;), the known label list includes &lt;code&gt;cat_meow&lt;/code&gt; and &lt;code&gt;cat_purr&lt;/code&gt; but not &lt;code&gt;cat_hiss&lt;/code&gt;. Always print &lt;code&gt;knownClassifications&lt;/code&gt; on the OS you ship; do not trust a mirrored label dump from 2021 alone.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does my hiss map to &lt;code&gt;snake_hiss&lt;/code&gt;?
&lt;/h3&gt;

&lt;p&gt;Same broadband turbulence family, different animal. Treat mid confidence on &lt;code&gt;snake_hiss&lt;/code&gt; as collision evidence for your gap report, not as a fact to show a pet owner.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can a lower meter threshold fix the missing class?
&lt;/h3&gt;

&lt;p&gt;No. A looser gate stores more files, including HVAC. You still lack &lt;code&gt;cat_hiss&lt;/code&gt;. Thresholds manage silence; they do not extend the ontology.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is &lt;code&gt;averagePower&lt;/code&gt; in dBFS?
&lt;/h3&gt;

&lt;p&gt;Yes. &lt;code&gt;0&lt;/code&gt; is full scale. Typical speech sits around −20 to −30. Room tone often sits near −50 to −60. That is why a mid-negative tripwire means "energy moved," not "cat hissed."&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I classify live with &lt;code&gt;SNAudioStreamAnalyzer&lt;/code&gt; instead of a file?
&lt;/h3&gt;

&lt;p&gt;Use the file probe first so permission, encoding, and labeling failures stay separable. Stream once the gap is proven and you still have a reason to listen continuously — knowing continuous listening will not create the missing class either.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is the next step always a custom Core ML model?
&lt;/h3&gt;

&lt;p&gt;Only if you need a first-party &lt;code&gt;cat_hiss&lt;/code&gt; label under your model card. If you need an owner-facing line after a hiss, that is outside classification. Build or buy the experience layer; do not force Sound Analysis to narrate intent it cannot see.&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>ios</category>
      <category>swift</category>
    </item>
  </channel>
</rss>
