سؤال
لديّ عازلة مع العديد من قيم 16 بت إيجابية (يتم تخزينها كضاعفة) وأود أن أعددها إلى 8bit (0-255 قيم).
بالنسبة الى ويكيبيديا ستكون العملية:
- قم بتطبيع قيم 16 بت. أي العثور على أكبر وتقسيم مع هذا.
- استخدم صيغة Q (x) مع M = 8.
لذلك أتساءل ، إذا كانت C لديها وظيفة يمكنها القيام بهذا القياس ، أم أن أي شخص يعرف تنفيذ C يمكنني استخدامه؟
الكثير من الحب ، لويز
المحلول
على افتراض القيمة d
في الفاصل الزمني [0.0, max]
:
unsigned char quantize(double d, double max)
{
return (unsigned char)((d / max) * 255.0);
}
لست متأكدًا مما تقصده بـ "القيم 16 بت" ؛ تكون قيم الدقة المزدوجة 64 بت على أي نظام باستخدام IEEE-754. ومع ذلك ، إذا كان لديك قيم من نوع رقمي آخر ، فإن العملية هي نفسها بشكل فعال.
نصائح أخرى
هذا يبدو مثل معالجة الصوت الموجي ، حيث يكون الإدخال الخاص بك هو 16 بيانات PCM ، والإخراج الخاص بك هو بيانات 8 بت PCM وأنت تستخدم الزوجي كقيمة وسيطة.
ومع ذلك ، فإن بيانات موجة PCM 8 بت ليست فقط كمية ، فإن التمثيل هو قيم غير موقعة تدوين 128. (مثل الطريقة التي يتم بها تخزين الأسس في أرقام النقاط العائمة)
إن العثور على أكبر قيمة أولاً لن يتم تحديد كمياتها فحسب ، بل أيضًا. لذلك في رمز الزائفة
double dMax = max_of_all_values(); //
...
foreach (dValue in array_of_doubles)
{
signed char bValue = (signed char)((dValue / dMax)*127.0);
}
يمكنك أن تتجول بدلاً من اقتطاعها إذا كنت تريد المزيد من الدقة ، ولكن في معالجة الصوت ، من الأفضل عمومًا وضع عشوائي لترتيب الاقتطاع أو حتى تشكيله عن طريق تشغيل خوارزمية تصفية بشكل أساسي كجزء من الاقتطاع من الزوجي إلى chars الموقعة.
ملاحظة: لا يكون هذا char الموقّع صحيحًا إذا كان الإخراج عبارة عن بيانات 8 بت PCM ، ولكن نظرًا لأن الأسئلة لا تطلب ذلك على وجه التحديد ، فقد تركتها.
تحرير: إذا تم استخدام هذا كبيانات بكسل ، فأنت تريد قيمًا غير موقعة. أرى أن جيمس أعطى بالفعل الإجابة الصحيحة للقيم غير الموقعة عندما تكون الإدخال غير موقعة (يجب أن تكون قيم DB من البيانات الطبيعية سلبية ، في الواقع)
ليس من الواضح من سؤالك ما هو الترميز منذ ذلك الحين "قيم 16 بت إيجابية (يتم تخزينها كضاعفة)"لا معنى له ، فهي إما 16 بت أو أنها ضعف ، لا يمكن أن تكون كلاهما.
ومع ذلك على افتراض أن هذه البيانات غير موقعة 16 بت تم تطبيعها إلى 1.0 (وبالتالي تتراوح القيم من 0.0 <= س <= 1.0) ، كل ما عليك القيام به لتوسيعها إلى قيم عدد صحيح 8bit هو ضرب كل عينة بمقدار 255.
unsigned char s8 = s * 255 ;
إذا لم يكن النطاق 0.0 <= س <= 1.0 ، لكن 0.0 <= s <= الأعلى من ثم:
unsigned char s8 = s / max * 255 ;
في كلتا الحالتين ، لا توجد وظيفة "كمية" بخلاف وظيفة قد تكتبها بنفسك ؛ لكن التحول اللازم سيكون بلا شك تعبيرًا حسابيًا بسيطًا (على الرغم من أنه ليس بسيطًا إذا تم تجميع البيانات ربما-أي μ-lay أو A-law مشفر على سبيل المثال).