Помогите, пожалуйста. Нужно переконвертировать WAV 16 бит в 12 бит. Какие алгоритмы, использовать? Ничего вообще про 12 бит не нашел. Существует ли вообще в природе такой формат?
zdacom Про 8-, 16-, 24-битные WAV знаю. О 12-битных слышу в первый раз. А что GOOGLE говрит об этом, или вас на нем заблокировали?
zdacom По-точнее нажми сюда первая же ссылка http://graphicon.ru/oldgr/courses/cg02b/assigns/hw-2/help/wavfmt2.htm но я знаю что карты Creative Sound Blaster 24-bit поддерживают 8-, 16-, 24 bit-depth. Возможно требуется написать перекодировщик, который будет превращать 16-битные WAV-файлы в 12-битные, такое-вот сжатие без сильной потери качества, а перед воспроизведением снова перекодировать 12-битные в 16-битные WAV-файлы
zdacom В той документации неоднократно встречаются упоминания 3х и 4х бит в wBitsPerSample, так что никаких принципальных ограничений на 12 бит быть не должно. Преобразовывать из 16 можно простым сдвигом вправо на 4 бита, соответсвенно младшие биты потеряются и останется только 12 старших. Будет ли это воспроизводиться чем нибудь из стандартных программ х.з. но раз даже 3 бита в природе встречается то возможно что и будет
Y_Mur, Phuntik Скорее не сдвигом, а перекрытием старшего нибла и "беззнаковым насыщением" если значение больше чем 2^12, то есть за счет потери старших битов -- IMHO потеря качества звучания будет незначительной
Mikl___ а почему "беззнаковым насыщением" если 16 битный формат согласно твоей же ссылке знаковый? Значит и сравнивать/насыщать нужно положительные и отрицательные значения по разному Кстати любопытный момент каким должен быть 12 битный знаковым как 16 или беззнаковым как 8 ) Phuntik Попробуй преобразовать в 12бит и в знаковый и беззнаковый вариант и попробовать на обычных плеерах. Конечно при переходе от 16 бит к 12 информация в большинстве случаев частично потеряется, другое дело как минимизировать эти потери. Тут возможны варианты: 1) запись ровная и с хорошим уровнем - лучше отбрасывать младшие биты, поскольку в них в основном шум. 2) запись ровная с низким уровнем, тогда проверить не содержат ли старшие биты во всей записи пустоту (0 для "+" и 1 для "-") тогда лучше отбросить их или частично пустые сверху (если их меньше 4) а остальные снизу. А ещё лучше в этом случае отмасштабировать запись (умножив все значения выборок на коэффициент) так чтобы самый громкий пик соответствовал пределу +-32767(8) и потом отбросить младшие биты. 3) запись с низким уровнем, но редкими "всплесками" - здесь лучше вариант Mikl___ просто обрезающий эти всплески (которые кстати могут оказаться помехами) до насыщения. 4) запись с периодическими переходами между громким и тихим звуком - лучше сделать АРУЗ (автоматический регулятор уровня звука) который будет анализировать запись, разбивая на участки (лучше переменной длины) и на тихих участках отбрасывать старшие биты, а на громких - младшие, в переходе между ними частично сверху, частично снизу. Хотя здесь тоже лучше ввести переменный коэффициент масштабирования зависящий от текущей громкости и всегда отбрасывать младшие биты после масштабирования. Это тоже потеря качества (сужение динамического диапазона) но приём широко применяется смирясь с неизбежными потерями, которые иногда на слух могут восприниматься и как улучшения звука
Y_Mur Ну, те четыре способа, что вы описали, скорее уже к обработке звука относятся. Мне представляется правильным самый простой и очевидный способ - привести диапазон 16 бит к 12 битам, т.е. k = 4096.0 / 65536.0. Принять, что исходные отсчёты беззнаковые 16-битные. Умножить каждый отсчёт на k. Вот и всё. Разве не так? Правка. А ведь действительно. Это получится деление на 16, т.е. сдвиг на четыре бита. Что-то я туго соображаю сегодня)
Phuntik k = 4096.0 / 65536.0. = 1/16 умножение на которую полностью эквивалентно сдвигу вправо на 4 ) соответсвенно на громкой записи (вариант 1) потери качества ты не заметишь, а в вариантах 2-4 можешь уже и заметить, а поскольку тебя это настораживает, то я и написал как с этим можно побороться нельзя см. ссылку от Mikl___, если конечно ты хочешь брать за исходные данные чужой звуковой файл, в котором выборки знаковые. Кстати с беззнаковм вариантом (см. про 8 бит) возни больше, так как там отсчёт в +- от 128 и его будет проще сначала в знаковый переформатировать
Phuntik Использовать SAR X,4 и тогда правильно обработаются и положительные и отрицательные значения. Y_Mur Если используются 16-ти битовые знаковые значения, а амплитуда звука "относительно" медленно нарастает или убывает, тогда знаковый бит можно сразу сэкономить, если, например, "договорится", что значение со всеми единицами соответствут "смене знака", а сигнал в самом начале положительный, еще один бит можно сэкономить, если ввести значения "смена диаппазона" -- допустим полный диаппазон от 0 до 5, делим его пополам, получаем два диаппазона от 0 до 2,4999 и от 2,5000 до 5.
Mikl___ Собственно сэкономить там можно не только знаковый бит, и не только на низкочастотных сигналах (создание эффективного алгоритма сжатия звука, особенно который может быть переплюнет mp3 - отдельная большая и интересная тема). Но здесь я так понял нужен всё-таки стандартный wav файл который может быть даже несмотря на свои странные 12 бит, воспроизведётся каким нибудь распространённым плеером Нестандартные решения с допсоглашениями по знаку точно обычными плеерами не распознаются.
Y_Mur Я понимаю, что решения на WASM.ru/forum часто опережают своей функциональностью, то, ЧТО просит заказчик, у них нет нашего опыта, а у нас -- нет их фантазии. Самым простым решением, было взять стандартный 16-битный WAV-файл, переделать его заголовок (wBitsPerSainple=12, общий размер=0,75х оригинальный размер), оторвать с 0-ого по 3-ий бит (или с 12-ого по 15-ый) и попробовать его воспроизвести на стандартном плеере. Если не пойдет, то в силе мой совет из #5 добавить к плееру проверку, если не 8, не 16 или не 24 бита (хотя копирование из WAV-файла в память звуковой карты скорее всего идет, через MOVSB или через MOVSW), то "перед воспроизведением снова перекодировать 12-битные в 16-битные WAV-файлы" и после этого воспроизводить
zdacom Берем и смотрим спецификацию. http://www-mmsp.ece.mcgill.ca/documents/audioformats/wave/Docs/riffmci.pdf 59 страница там про 12 бит идет пояснение. Только вот это спецификации противоречит. http://www-mmsp.ece.mcgill.ca/documents/audioformats/wave/wave.html Тут про все разновидности wav лучше всех описано.
Ну и зачем хранить знак рассширенный до 4 бит? Алгоритм сжатия-распаковки напрашивается сам собой, на пример так Код (Text): .data string1 dw 0123h,0456h,0F879h,0FABCh string2 dw 3 dup (0) string3 dw 4 dup (0) .code mov edi,offset string2 mov esi,offset string1 ; сжатие movsb lodsw and ax,0FF0Fh rol ax,4 stosw lodsb and al,0Fh or [edi-1],al movsb lodsw and ax,0FF0Fh rol ax,4 stosw lodsb and al,0Fh or [edi-1],al ... mov edi,offset string3 mov esi,offset string2 ; распаковка movsb lodsw ror ax,4 shl al,4 sar al,4 stosw mov al,[esi-1] shl al,4 sar al,4 stosb movsb lodsw ror ax,4 shl al,4 sar al,4 stosw mov al,[esi-1] shl al,4 sar al,4 stosb