diff --git a/frame.c b/frame.c
index 7b4fa4ddf53f215c6713e5da7046d86b6b4ec52e..39bed2e01d513ef186a769e09591c2bb77615c5b 100755
--- a/frame.c
+++ b/frame.c
@@ -1263,9 +1263,9 @@ int ast_frame_adjust_volume(struct ast_frame *f, int adjustment)
 
 	for (count = 0; count < f->samples; count++) {
 		if (adjustment > 0) {
-			fdata[count] *= abs(adjustment);
+			ast_slinear_saturated_multiply(&fdata[count], abs(adjustment));
 		} else if (adjustment < 0) {
-			fdata[count] /= abs(adjustment);
+			ast_slinear_saturated_divide(&fdata[count], abs(adjustment));
 		}
 	}
 
diff --git a/include/asterisk/utils.h b/include/asterisk/utils.h
index e0c32597dece6cf846742d4c628c2fea14579867..9aa1a34c3f8acbba66327ff15c9c0cd4f3e65553 100755
--- a/include/asterisk/utils.h
+++ b/include/asterisk/utils.h
@@ -168,7 +168,37 @@ char *ast_uri_encode(char *string, char *outbuf, int buflen, int doreserved);
 	\param s	String to be decoded 
  */
 void ast_uri_decode(char *s);
+
+static inline void ast_slinear_saturated_add(short *input, short value)
+{
+	int res;
+
+	res = *input + value;
+	if (res > 32767)
+		*input = 32767;
+	else if (res < -32767)
+		*input = -32767;
+	else
+		*input = (short) res;
+}
 	
+static inline void ast_slinear_saturated_multiply(short *input, short value)
+{
+	int res;
+
+	res = *input * value;
+	if (res > 32767)
+		*input = 32767;
+	else if (res < -32767)
+		*input = -32767;
+	else
+		*input = (short) res;
+}
+
+static inline void ast_slinear_saturated_divide(short *input, short value)
+{
+	*input /= value;
+}
 
 extern int test_for_thread_safety(void);