![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Работа со звуком в Turbo Pascal 7.0
Александиров © (2008-10-31 11:53:00)Нашёл в Интернете пример программы работы со звуком:
Program MusicColor;
Uses Crt, Graph; {подключение к программе библиотек Crt и Graph}
Var
GrDriver, GrMode: Integer; {тип и режим работы графического драйвера}
BEGIN
GrDriver := Detect; {автоопределение типа графического драйвера}
InitGraph(GrDriver, GrMode, 'C:\TP\BGI'); {установка графического режима}
SetColor(White); {установка белого цвета рамки }
Rectangle(130, 130, 460, 370); {рисование рамки }
Randomize; {инициализация датчика случайных чисел}
Repeat {цикл прерывается нажатием любой клавиши}
Sound(Random(2000)); {изменение высоты звука }
Delay(Random(1000)); {задержка }
SetFillStyle(Random(4), Random(16)); {смена типа штриховки и цвета}
Bar(140, 140, 450, 360); {рисование закрашенного прямоугольника}
until KeyPressed;
NoSound; {отмена звука }
CloseGraph; ReadLn; {закрытие графического режима}
END.
Компилирию - всё нормально, запускаю на выполнение выдаёт ошибку: Error 200: Division by zero
Упрощаю программу:
Program Music;
Uses Crt;
BEGIN
Sound(1000);
Delay(1000);
NoSound;
END.
Всё равно выдаёт туже ошибку. Подскажите почему, что я делаю не так?
Anatoly Podgoretsky (2008-10-31 17:04:00) [1]> Palladin (31.10.2008 16:58:22) [22]
Я уверено говорю, потому что тот код у меня как перед глазами, на всю жизнь запомнил.
Алгоритм там простой, в цикле, в течение 55 мсек (полный оборот таймера и прерывание) на каждой итеррации наращивается счетчкик, по окончанию счетчик делится на 55, для получения интервала в 1 мсек, что далее используется в функции Delay. По мере роста частот, счетчик стал переполняться.
Palladin (2008-10-31 16:58:00) [2]
> Вообще то ошибаешсь
так и знал, значит воспоминания из какой то другой оперы...
Anatoly Podgoretsky (2008-10-31 16:57:00) [3]> Palladin (31.10.2008 16:23:18) [18]
Вообще то ошибаешсь, именно происходит деление на 55 накопленного за 55 мсек счетчика.
В результате деления долно получиться меньше или равно 65535, а счетчик много больше 65536*55
У меня претензии не к реализации, а к сообщению об ошибке. И к этому приложили руку два этих гиганта, Интел более виноват.
Сергей М. (2008-10-31 16:30:00) [4]
> мне непорятно зачем они назвали Division by zero/Divide
> by zero
Мне тоже.
Поэтому и предполагаю, что это банальный ляп.
> это частный случай
Это как ?
Ошибка деления на ноль есть частный случай ошибки переполнения, ты это имел ввиду ?
Ну дальнее родство тут, конечно, имеется, но ошибка-то возбуждается не по родству, а конкретно либо по прерыванию (причина - деление на ноль) либо по анализу установленного флага OF (как результат переполнения при выполнении арифм.инструкции)
Anatoly Podgoretsky (2008-10-31 16:30:00) [5]
> Amoeba © (31.10.08 14:31) [13]
Именно этот сайт и имел в виду, там объяеснение и несколько лечилок разного уровня.
Palladin (2008-10-31 16:23:00) [6]Насколько я помню, ошибка возникает не в результате деления на 55, а в результате деления на результат деления на 55. :) Нехватило там точности для результата деления на 55 :)... и, конечно, вполне могу и ошибаться...
Германн (2008-10-31 16:22:00) [7]
> Сергей М. © (31.10.08 14:55) [14]
>
>
> > Anatoly Podgoretsky © (31.10.08 14:01) [12]
>
>
> > претензии к Интел и ИБМ
> >
>
>
> Довольно странно пенять на железных брендов, в то время
> как видимая часть проблемы в элементарном ляпе софтового
> бренда)
>
+1
Вот в TpCrt такого ляпа нет и не было, а он более старый, чем Crt от ТР7.
Anatoly Podgoretsky (2008-10-31 16:21:00) [8]> Сергей М. (31.10.2008 14:55:14) [14]
А мне непорятно зачем они назвали Division by zero/Divide by zero
Когда это частный случай, в данном случае ошибка возникает при деление на 55 (пятьдесят пять)
Jeer (2008-10-31 15:03:00) [9]Как быстро все забывается, а ведь десять лет - не такое уж большое время.
Вспомнить, хотя бы, примерно аналогичную проблему на Clipper-e.
Сергей М. (2008-10-31 14:55:00) [10]
> Anatoly Podgoretsky © (31.10.08 14:01) [12]
> претензии к Интел и ИБМ
>
Довольно странно пенять на железных брендов, в то время как видимая часть проблемы в элементарном ляпе софтового бренда)
Нет бы написать, мол, приключилось переполнение)
Amoeba (2008-10-31 14:31:00) [11]
> Компилирию - всё нормально, запускаю на выполнение выдаёт
> ошибку: Error 200: Division by zero
Объяснение причины и решение найдешь здесь:
http://www.brain.uni-freiburg.de/~klaus/pascal/runerr200/
Anatoly Podgoretsky (2008-10-31 14:01:00) [12]> Сергей М. (31.10.2008 12:37:08) [8]
Все претензии к Интел и ИБМ
Рамиль (2008-10-31 13:46:00) [13]DosBox не поможет?
Vlad Oshin (2008-10-31 13:13:00) [14]
> чтобы получить эту ошибку, достаточно uses crt сделать
согласен, забыл
DrPass (2008-10-31 12:48:00) [15]
> или переписать delay процедуру
> навроде
> var=gettime;
> repeat
> until gettime>var+DelayVar;
Не получится. Расчет интервалов для Delay производится в секции инициализации модуля Crt (естественно, не той, которая initialization, ее в Паскале не было). Т.е. чтобы получить эту ошибку, достаточно uses crt сделать
Сергей М. (2008-10-31 12:37:00) [16]
> Anatoly Podgoretsky © (31.10.08 12:24) [7]
> Division by zero - .. это ошибка деления на 55
Ну ты, Анатолий, и загнул)
Деление на ноль - это, оказывается, ничто иное как деление на 55)
Эдаким заявлением можно запросто кого-угодно поставить в ступор, ввергнуть в состояние глубокого травматического мозгового шока)
Anatoly Podgoretsky (2008-10-31 12:24:00) [17]> Александиров (31.10.2008 12:01:03) [3]
Никакой, надо процедуры работы с таймером переводить на 32 бита. Все остальные патчи дают только частичные или вообще неверную работу. Надо просто сделать поиск по проблеме в Интернете и найти сайт, где собраны методы борьбы. Патчи используют если нет исходников, а при наличии исходников, просто переписывают модуль CRT
Division by zero - на самом деле реальная ошибка, это ошибка деления на 55. Цикл работы системного таймера = 55 мс.
Vlad Oshin (2008-10-31 12:06:00) [18]
> А как можно это исправить?
> "патч" модуля Crt
> Поищи...
или переписать delay процедуру
навроде
var=gettime;
repeat
until gettime>var+DelayVar;
Александиров (2008-10-31 12:03:00) [19]Спасибо, поищу
Александиров (2008-10-31 12:03:00) [20]Спасибо, поищу