+ return (pa_volume_t) p;
+}
+
+pa_volume_t pa_volume_from_dB(double f) {
+ if (f <= PA_DECIBEL_MININFTY)
+ return PA_VOLUME_MUTED;
+
+ return (pa_volume_t) (pow(10, f/20)*PA_VOLUME_NORM);
+}
+
+double pa_volume_to_dB(pa_volume_t v) {
+ if (v == PA_VOLUME_MUTED)
+ return PA_DECIBEL_MININFTY;
+
+ return 20*log10((double) v/PA_VOLUME_NORM);
+}
+
+#define USER_DECIBEL_RANGE 30
+
+double pa_volume_to_user(pa_volume_t v) {
+ double dB = pa_volume_to_dB(v);
+
+ return dB < -USER_DECIBEL_RANGE ? 0 : dB/USER_DECIBEL_RANGE+1;
+}
+
+pa_volume_t pa_volume_from_user(double v) {
+
+ if (v <= 0)
+ return PA_VOLUME_MUTED;
+
+ return pa_volume_from_dB((v-1)*USER_DECIBEL_RANGE);
+}
+
+void pa_bytes_snprint(char *s, size_t l, unsigned v) {
+ if (v >= ((unsigned) 1024)*1024*1024)
+ snprintf(s, l, "%0.1f GB", ((double) v)/1024/1024/1024);
+ else if (v >= ((unsigned) 1024)*1024)
+ snprintf(s, l, "%0.1f MB", ((double) v)/1024/1024);
+ else if (v >= (unsigned) 1024)
+ snprintf(s, l, "%0.1f KB", ((double) v)/1024);
+ else
+ snprintf(s, l, "%u B", (unsigned) v);
+}
+
+enum pa_sample_format pa_parse_sample_format(const char *format) {
+
+ if (strcmp(format, "s16le") == 0)
+ return PA_SAMPLE_S16LE;
+ else if (strcmp(format, "s16be") == 0)
+ return PA_SAMPLE_S16BE;
+ else if (strcmp(format, "s16ne") == 0 || strcmp(format, "s16") == 0 || strcmp(format, "16") == 0)
+ return PA_SAMPLE_S16NE;
+ else if (strcmp(format, "u8") == 0 || strcmp(format, "8") == 0)
+ return PA_SAMPLE_U8;
+ else if (strcmp(format, "float32") == 0 || strcmp(format, "float32ne") == 0)
+ return PA_SAMPLE_FLOAT32;
+ else if (strcmp(format, "float32le") == 0)
+ return PA_SAMPLE_FLOAT32LE;
+ else if (strcmp(format, "float32be") == 0)
+ return PA_SAMPLE_FLOAT32BE;
+ else if (strcmp(format, "ulaw") == 0)
+ return PA_SAMPLE_ULAW;
+ else if (strcmp(format, "alaw") == 0)
+ return PA_SAMPLE_ALAW;
+
+ return -1;