diff --git a/trunk/src/engines/sfz/Engine.cpp b/trunk/src/engines/sfz/Engine.cpp
index 1177503..d80f462 100644
--- a/trunk/src/engines/sfz/Engine.cpp
+++ b/trunk/src/engines/sfz/Engine.cpp
@@ -275,6 +275,8 @@ namespace LinuxSampler { namespace sfz {
 
         if (HandleKeyGroupConflicts) pChannel->HandleKeyGroupConflicts(pRgn->group, itNoteOnEvent);
 
+        pChannel->HandlePolyphony(pRgn, itNoteOnEvent);
+
         // no need to process if sample is silent
         if (!pRgn->GetSample(false) || !pRgn->GetSample()->GetTotalFrameCount()) return Pool<Voice>::Iterator();
 
diff --git a/trunk/src/engines/sfz/EngineChannel.cpp b/trunk/src/engines/sfz/EngineChannel.cpp
index 8f312e3..aa2e506 100644
--- a/trunk/src/engines/sfz/EngineChannel.cpp
+++ b/trunk/src/engines/sfz/EngineChannel.cpp
@@ -197,4 +197,64 @@ namespace LinuxSampler { namespace sfz {
         PressedKeys[key] = false;
     }
 
+    void EngineChannel::HandlePolyphony(::sfz::Region* pRegionToPlay, Pool<Event>::Iterator& itEvent) {
+        // If there's a need to process (region is in the group with polyphony
+        // or has note_polyphony set)
+        if ((pRegionToPlay->group != 0 && pRegionToPlay->polyphony != 0)
+          || pRegionToPlay->note_polyphony != 0)
+        {
+            typedef std::multimap<sched_time_t, RTListVoiceIterator> VoiceMap;
+            VoiceMap orderedVoices;
+            RTList<uint>::Iterator iuiKey = this->pActiveKeys->first();
+            RTList<uint>::Iterator end = this->pActiveKeys->end();
+            for (; iuiKey != end; ++iuiKey) { // iterate through all active keys
+                MidiKey* pKey = &this->pMIDIKeyInfo[*iuiKey];
+                for (RTListNoteIterator itNote = pKey->pActiveNotes->first(),
+                     itNotesEnd = pKey->pActiveNotes->end();
+                     itNote != itNotesEnd; ++itNote)
+                {
+                    RTListVoiceIterator itVoice = itNote->pActiveVoices->first();
+                    RTListVoiceIterator itVoicesEnd = itNote->pActiveVoices->end();
+                    for (; itVoice != itVoicesEnd; ++itVoice)  // iterate through all voices on this key
+                    {
+                        // Add voice to the multimap ordered by trigger time
+                        orderedVoices.insert(VoiceMap::value_type(itVoice->pNote->triggerSchedTime, itVoice));
+                    }
+                }
+            }
+
+            int group_count = 0;
+            int note_count = 0;
+
+            // Iterate in reverse order to save most recent voices and 
+            // kill those from the beginning of the list (triggered earlier)
+            for (VoiceMap::reverse_iterator itMap = orderedVoices.rbegin(); itMap != orderedVoices.rend(); ++itMap) {
+                RTListVoiceIterator itVoice = itMap->second;
+                ::sfz::Region* pRegion = itVoice->GetRegion();
+                bool killByGroup = false;
+                bool killByNote  = false;
+                if (pRegion->group == pRegionToPlay->group) {
+                    ++group_count;
+                    killByGroup = (pRegionToPlay->polyphony != 0)
+                               && (group_count >= pRegionToPlay->polyphony);
+                }
+                if (itEvent->Param.Note.Key == itVoice->pNote->hostKey) {
+                    ++note_count;
+                    killByNote = (pRegionToPlay->note_polyphony != 0)
+                              && (note_count >= pRegionToPlay->note_polyphony);
+                }
+
+                if (killByGroup || killByNote) {
+                    if (pRegion->off_mode == ::sfz::OFF_NORMAL) {
+                        // turn off the voice by entering release envelope stage
+                        itVoice->EnterReleaseStage();
+                    } else {
+                        // kill the voice fast
+                        itVoice->Kill(itEvent);
+                    }
+                }
+            }
+        }
+    }
+
 }} // namespace LinuxSampler::sfz
diff --git a/trunk/src/engines/sfz/EngineChannel.h b/trunk/src/engines/sfz/EngineChannel.h
index d2a4390..7c6a19a 100644
--- a/trunk/src/engines/sfz/EngineChannel.h
+++ b/trunk/src/engines/sfz/EngineChannel.h
@@ -55,6 +55,7 @@ namespace LinuxSampler { namespace sfz {
             virtual ~EngineChannel();
 
             virtual void ProcessKeySwitchChange(int key) OVERRIDE;
+            void HandlePolyphony(::sfz::Region* pRegionToPlay, Pool<Event>::Iterator& itEvent);
 
         private:
             bool PressedKeys[128];
diff --git a/trunk/src/engines/sfz/sfz.cpp b/trunk/src/engines/sfz/sfz.cpp
index 417bc54..e76f64a 100755
--- a/trunk/src/engines/sfz/sfz.cpp
+++ b/trunk/src/engines/sfz/sfz.cpp
@@ -332,6 +332,8 @@ namespace sfz
         group = 0;
         off_by = 0;
         off_mode = OFF_FAST;
+        polyphony = 0;
+        note_polyphony = 0;
 
         // sample player
         count = optional<int>::nothing;
@@ -639,6 +641,8 @@ namespace sfz
         definition->group = group;
         definition->off_by = off_by;
         definition->off_mode = off_mode;
+        definition->polyphony = polyphony;
+        definition->note_polyphony = note_polyphony;
         definition->on_locc = on_locc;
         definition->on_hicc = on_hicc;
 
@@ -1583,6 +1587,8 @@ namespace sfz
             if (value == "fast")  pCurDef->off_mode = OFF_FAST;
             else if (value == "normal") pCurDef->off_mode = OFF_NORMAL;
         }
+        else if ("polyphony" == key) pCurDef->polyphony = ToInt(value);
+        else if ("note_polyphony" == key) pCurDef->note_polyphony = ToInt(value);
 
         // sample player
         else if ("count" == key) { pCurDef->count = ToInt(value); pCurDef->loop_mode = ONE_SHOT; }
diff --git a/trunk/src/engines/sfz/sfz.h b/trunk/src/engines/sfz/sfz.h
index 7b36b2e..0de128d 100755
--- a/trunk/src/engines/sfz/sfz.h
+++ b/trunk/src/engines/sfz/sfz.h
@@ -430,6 +430,8 @@ namespace sfz
         uint group;
         uint off_by;
         off_mode_t off_mode;
+        uint polyphony;
+        uint note_polyphony;
 
         Array<int> on_locc; Array<int> on_hicc;
 
