Дикая розаExactMouse 1.21

Comments (15):

  • Отстойный же кодек - хуже Lame-а гораздо. Не говоря уже про Vorbis-ы всякие.
    • ёлы..так я и хочу разобрать (наведи мышь на курсив) LAME.

      просто неважно что разбирать..у меня и исходники-то только lame и есть...
      • Я по контексту посчитал, что ты про Фраунхоферовский кодек говоришь...

        А что, тебе скорости энкодинга Lame-ом не хватает? А ты проапгрейдься на процессор с SSE2, а ещё лучше AMD64, и скомпилируй Лэйм соответственно. И меньше времени потратишь, и работать быстрее будет.
        • да нет! ;)
          мне интересен сам процесс.. чтобы самому лично понять алгоритм.. понимаешь?

          если же читать описание алгоритма или разбирать исходники, то может быть и можно узнать, но труднее..
          • > если же читать описание алгоритма или разбирать исходники, то может быть и
            > можно узнать, но труднее..

            %))))))
            До тебя ещё никто не говорил, что самый просто способ понимания алгоритма - это переписывание его на ассемблере :)
            По-моему, это всё равно что рассматривать пятимегапиксельную картинку пиксель за пикселем :)))

            Вот тебе краткое описание, кстати. Лаконичное. //en.wikipedia.org/wiki/MP3#Overview
            • сравнение неправильное (с картинкой).

              и что там за описание??? это просто краткое описание...а мне нужен алгоритм! ну типа блок схема хотя бы.
              • > сравнение неправильное (с картинкой).
                Как это - неправильное? За деревьями не будет видно леса. За нереально большой кучей мелочей не сложится цельной картины.
                • ёлы..а кто сказал, что я буду только однобоко рассматривать, а не во всех плоскостях???
                  • Ты. Ты же сказал - "переписывать на ассемблере". А значит - заниматься исключительно низкоуровневой оптимизацией. Самым последним и детализированным этапом. Всё равно что картинку попиксельно править :)
                    • у тебя странное мнение о языке Ассемблер.

                      ну если ты не умеешь его использовать, то это твои проблемы.
                      • Поверь мне, я умею использовать язык Ассемблер. Причём на нескольких платформах.
                        Но помимо них, я умею использовать ещё пару десятков языков.
                        Что даёт мне возможность сравнивать его с ними.

                        При этом я совершенно не спорю, что, если не знать других языков, то ассемблер предоставляет очень неплохой высокий уровень абстракций :)
                        • я тоже не буду спорить...
                        • Конкретнее: ассемблер предоставляет простейшие возможности по описанию алгоритма как последовательности наипростейших действий. Сборка кубиков из песчинок. Исключительно императивный подход. В нём нет

                          *1. нормальных возможностей расширения самого языка (как в Forth, Lisp и т.п.)

                          *2. возможностей перекладывания описания процесса решения задачи на компилятор, а вместо этого описания только зависимостей между исходными данными и постановки цели (как в Prolog и SQL-е)

                          *3. возможностей описывать алгоритмы, не привязанные ни к каким структурам данных (как при метапрограммировании на куче языков, от С++-а с жабой и сишарпом до того же Лиспа)

                          *4. нормальных средств отслеживания ограничений на данные и зависимости между ними (т.е., design-by-contract, как в Eiffel-е).


                          Поясню на примерах, что конкретно я имею в виду:

                          *1. В том же Лиспе нет, кажется, ни единственного ключевого слова собственно языка. Все его сущности являются списками и могут быть расширены или переопределены; с другой стороны, никто не мешает определить в нём сходные, но отсутствующие элементы. Например, если нет итератора while, но есть, допустим, итератор for, то можно создать этот while самостоятельно, и в использовании он не будет ничем принципиально отличаться от того же for - будет казаться, что он такой же элемент языка.

                          *2. в императивных языках ты описываешь последовательность шагов для решения задачи. "Чиркнуть спичкой о коробок, повернуть ручку плиты, поднести спичку к конфорке". В логических языках ты описываешь взаимосвязи между элементами и ставишь цель, а последовательность шагов компилятор создаёт сам. "Если к газу поднести огонь, то газ загорится. Если чиркнуть спичкой о коробок, то спичка загорится. Если повернуть ручку плиты, то из конфорки пойдёт газ. Задача: зажечь газ в конфорке". В случаях, когда алгоритм простой, это не требуется... но можешь попробовать написать алгоритм решения типичных олимпиадных задач наподобие "Немец живёт в доме рядом с владельцем кошки" :)

                          *3. Среднее количество между двумя величинами - это сумма этих величин, делённая на количество этих величин. В этом описании ни разу не прозвучало требование к типу величин, среднее количество между которыми мы вычисляем. Это может быть количество апельсинов в бочках, количество срабатываний упса в день, количество машин, останавливающихся перед светофором при каждом включении красного света. Поэтому алгоритм, находящий такой среднее количество не должен в свою очередь накладывать таких ограничений на тип данных - он должен быть применим к любым сущностям, которые можно сложить между собой, и результат сложения поделить на число.

                          Равно как алгоритм сортировки пузырьком не должен интересоваться, сортируем мы целые числа по их величине, заданные своими вершинами многоугольники по их площади, страны мира по количеству смертей в год от попадания под лошадь или тексты Ленина по количеству упоминаний слова "революция" в них. Единственное, что нужно алгоритму сортировки пузырьком - это возможность переставлять элементы в том контейнере, в котором он их принимает, да возможность сравнивать эти элементы между собой по какому-нибудь признаку, получая ответ "больше/меньше/равен".
                          • *4. Когда пишешь большую программу с очень серьёзными требованиями к надёжности, приходится не только тщательно тестировать её, но и обеспечивать какие-то средства, чтобы надёжность программы не ухудшилась в будущем. А ухудшиться она может, например, из-за того, что следующие люди, которые будут её модифицировать, не учтут какого-нибудь фактора или зависимости, которая была тебе известна. Или ты сам опечатаешься или не учтёшь чего-то. Или чей-нибудь код выполнится не так, как ты ожидаешь.

                            Поэтому при написании таких систем, чтобы обезопаситься от ошибок, максимально ограничиваешь выполняемый код в рамках того, что и как он может делать. На С и С++, например, есть замечательная функция (или макрос препроцессора - не знаю) assert - оный принимает один аргумент, вычисляет его, и продолжает работу дальше.

                            Например, пишешь ты какой-нибудь код, который работает с одним сэмплом 16-битного звука. Например, в цикле по переменной i проходишь по массиву samples, так, что samples[i] - это твой текущий сэмпл, и для каждого сэмпла дёргаешь некую внешнюю функцию, которая в этом массиве правит именно этот сэмпл по его индексу. Как-то правит, неважно как, но ты знаешь одно - новое значение точно не может быть больше старого. Причём боишься, что в будущем кто-нибудь - ты сам, или кто будет это править - например, имплементировать эту функцию на ассемблере для новой платформы - может в этом месте ошибиться. Вот и защищаешься от этой ошибки:
                            oldsample = samples[i];
                            process_and_update_sample(samples, i);
                            assert (oldsample >= samples[i]);

                            Всё, теперь ты не боишься будущего :)

                            А языки типа Эйфеля позволяют идти дальше. Для каждой функции указывать её предусловия и постусловия, так что они вписываются прямо в описание функции, да заодно помогают не только компилятору, но и человеку, пользующемуся этой функцией, видеть, что "эта функция всегда принимает непустые списки и возвращает непустые списки". Для каждого класса указывать инварианты, которые верны для элементов этого класса, что бы ни случилось ("какие бы операции с классом "класс" не делались, сумма элементов массива "мальчики" и элементов массива "девочки" не больше тридцати").