Browse Source

Plan 9 from Bell Labs 2007-11-28

David du Colombier 12 years ago
parent
commit
492daa80aa
100 changed files with 40810 additions and 55786 deletions
  1. 112 10
      dist/replica/_plan9.db
  2. 111 10
      dist/replica/plan9.db
  3. 17494 55716
      dist/replica/plan9.log
  4. 1 1
      lib/ndb/auth
  5. 3 2
      sys/include/frame.h
  6. BIN
      sys/lib/music/icon/cross.bit
  7. BIN
      sys/lib/music/icon/down.bit
  8. BIN
      sys/lib/music/icon/exit.bit
  9. BIN
      sys/lib/music/icon/grey.bit
  10. BIN
      sys/lib/music/icon/minus.bit
  11. BIN
      sys/lib/music/icon/next.bit
  12. BIN
      sys/lib/music/icon/pause.bit
  13. BIN
      sys/lib/music/icon/play.bit
  14. BIN
      sys/lib/music/icon/prev.bit
  15. BIN
      sys/lib/music/icon/question.bit
  16. BIN
      sys/lib/music/icon/root.bit
  17. BIN
      sys/lib/music/icon/select.bit
  18. BIN
      sys/lib/music/icon/skull.bit
  19. BIN
      sys/lib/music/icon/stop.bit
  20. BIN
      sys/lib/music/icon/trash.bit
  21. BIN
      sys/lib/music/icon/up.bit
  22. BIN
      sys/lib/music/icon/volume.bit
  23. 209 0
      sys/man/1/mp3enc
  24. 25 8
      sys/src/9/pc/l.s
  25. 4 2
      sys/src/9/pc/mem.h
  26. 29 26
      sys/src/9/pc/memory.c
  27. 1 1
      sys/src/9/port/devdup.c
  28. 123 9
      sys/src/cmd/replica/applylog.c
  29. 1 1
      sys/src/cmd/rio/wind.c
  30. 266 0
      sys/src/games/mp3dec/audio.c
  31. 89 0
      sys/src/games/mp3dec/audio.h
  32. 48 0
      sys/src/games/mp3dec/audio_dummy.c
  33. 231 0
      sys/src/games/mp3dec/buffer.c
  34. 13 0
      sys/src/games/mp3dec/buffer.h
  35. 732 0
      sys/src/games/mp3dec/common.c
  36. 22 0
      sys/src/games/mp3dec/common.h
  37. 337 0
      sys/src/games/mp3dec/control_generic.c
  38. 168 0
      sys/src/games/mp3dec/dct64.c
  39. 223 0
      sys/src/games/mp3dec/decode.c
  40. 231 0
      sys/src/games/mp3dec/decode_2to1.c
  41. 238 0
      sys/src/games/mp3dec/decode_4to1.c
  42. 288 0
      sys/src/games/mp3dec/decode_ntom.c
  43. 37 0
      sys/src/games/mp3dec/equalize.dat
  44. 34 0
      sys/src/games/mp3dec/equalizer.c
  45. 263 0
      sys/src/games/mp3dec/genre.h
  46. 127 0
      sys/src/games/mp3dec/getbits.c
  47. 33 0
      sys/src/games/mp3dec/getbits.h
  48. 129 0
      sys/src/games/mp3dec/getlopt.c
  49. 66 0
      sys/src/games/mp3dec/getlopt.h
  50. 353 0
      sys/src/games/mp3dec/httpget.c
  51. 332 0
      sys/src/games/mp3dec/huffman.h
  52. 154 0
      sys/src/games/mp3dec/l2tables.h
  53. 155 0
      sys/src/games/mp3dec/layer1.c
  54. 296 0
      sys/src/games/mp3dec/layer2.c
  55. 1869 0
      sys/src/games/mp3dec/layer3.c
  56. 67 0
      sys/src/games/mp3dec/mkfile
  57. 1202 0
      sys/src/games/mp3dec/mpg123.c
  58. 370 0
      sys/src/games/mp3dec/mpg123.h
  59. 488 0
      sys/src/games/mp3dec/readers.c
  60. 153 0
      sys/src/games/mp3dec/tabinit.c
  61. 193 0
      sys/src/games/mp3dec/term.c
  62. 39 0
      sys/src/games/mp3dec/term.h
  63. 3 0
      sys/src/games/mp3dec/version.h
  64. 279 0
      sys/src/games/mp3dec/wav.c
  65. 279 0
      sys/src/games/mp3dec/xfermem.c
  66. 60 0
      sys/src/games/mp3dec/xfermem.h
  67. 49 0
      sys/src/games/mp3enc/README
  68. 575 0
      sys/src/games/mp3enc/VbrTag.c
  69. 76 0
      sys/src/games/mp3enc/VbrTag.h
  70. 880 0
      sys/src/games/mp3enc/bitstream.c
  71. 37 0
      sys/src/games/mp3enc/bitstream.h
  72. 53 0
      sys/src/games/mp3enc/brhist.h
  73. 584 0
      sys/src/games/mp3enc/encoder.c
  74. 131 0
      sys/src/games/mp3enc/encoder.h
  75. 289 0
      sys/src/games/mp3enc/fft.c
  76. 37 0
      sys/src/games/mp3enc/fft.h
  77. 1618 0
      sys/src/games/mp3enc/get_audio.c
  78. 100 0
      sys/src/games/mp3enc/get_audio.h
  79. 539 0
      sys/src/games/mp3enc/id3tag.c
  80. 30 0
      sys/src/games/mp3enc/id3tag.h
  81. 100 0
      sys/src/games/mp3enc/l3side.h
  82. 90 0
      sys/src/games/mp3enc/lame-analysis.h
  83. 1852 0
      sys/src/games/mp3enc/lame.c
  84. 953 0
      sys/src/games/mp3enc/lame.h
  85. 26 0
      sys/src/games/mp3enc/lameerror.h
  86. 89 0
      sys/src/games/mp3enc/lametime.c
  87. 35 0
      sys/src/games/mp3enc/lametime.h
  88. 147 0
      sys/src/games/mp3enc/machine.h
  89. 293 0
      sys/src/games/mp3enc/main.c
  90. 45 0
      sys/src/games/mp3enc/main.h
  91. 2 0
      sys/src/games/mp3enc/memory.h
  92. 65 0
      sys/src/games/mp3enc/mkfile
  93. 185 0
      sys/src/games/mp3enc/mpglib_interface.c
  94. 792 0
      sys/src/games/mp3enc/newmdct.c
  95. 28 0
      sys/src/games/mp3enc/newmdct.h
  96. 1236 0
      sys/src/games/mp3enc/parse.c
  97. 8 0
      sys/src/games/mp3enc/parse.h
  98. 1609 0
      sys/src/games/mp3enc/pcm.c
  99. 277 0
      sys/src/games/mp3enc/pcm.h
  100. 0 0
      sys/src/games/mp3enc/portableio.c

+ 112 - 10
dist/replica/_plan9.db

@@ -260,6 +260,8 @@
 386/bin/games/jukefs - 775 sys sys 1105589129 165320
 386/bin/games/mahjongg - 775 sys sys 1191381911 165242
 386/bin/games/memo - 775 sys sys 1179372089 156656
+386/bin/games/mp3dec - 755 sys sys 1196207154 355822
+386/bin/games/mp3enc - 775 sys sys 1196220182 530357
 386/bin/games/playlistfs - 775 sys sys 1105589129 148484
 386/bin/games/sokoban - 775 sys sys 1179372090 165514
 386/bin/games/sudoku - 775 sys sys 1179372090 171015
@@ -5244,7 +5246,7 @@ lib/namespace - 664 sys sys 1176262168 619
 lib/namespace.ftp - 664 sys sys 1020313578 373
 lib/namespace.httpd - 664 sys sys 984695868 1209
 lib/ndb - 20000000775 sys sys 1065569740 0
-lib/ndb/auth - 664 sys sys 1117108784 572
+lib/ndb/auth - 664 sys sys 1196183272 571
 lib/ndb/common - 664 sys sys 1133553666 5376
 lib/ndb/consoledb - 664 sys sys 960222421 95
 lib/ndb/dhcp - 20000000775 sys sys 1020895764 0
@@ -6092,7 +6094,7 @@ sys/include/draw.h - 664 sys sys 1108655526 16144
 sys/include/event.h - 664 sys sys 1014929063 1426
 sys/include/fcall.h - 664 sys sys 1137461445 3063
 sys/include/flate.h - 664 sys sys 1014929063 1245
-sys/include/frame.h - 664 sys sys 1147706379 2682
+sys/include/frame.h - 664 sys sys 1196212617 2708
 sys/include/geometry.h - 664 sys sys 1014929063 2632
 sys/include/html.h - 664 sys sys 1184472600 15622
 sys/include/httpd.h - 664 sys sys 1190835025 5800
@@ -7428,6 +7430,7 @@ sys/man/1/mc - 664 sys sys 1113743326 552
 sys/man/1/mk - 664 sys sys 1113743328 13198
 sys/man/1/mkdir - 664 sys sys 1082593141 717
 sys/man/1/mlmgr - 664 sys sys 1116513886 2542
+sys/man/1/mp3enc - 664 sys sys 1196208904 3236
 sys/man/1/ms2html - 664 sys sys 1138458899 1252
 sys/man/1/mug - 664 sys sys 1158800370 1424
 sys/man/1/nedmail - 664 sys sys 1159419884 6821
@@ -8120,10 +8123,10 @@ sys/src/9/pc/init9.c - 664 sys sys 1040002518 94
 sys/src/9/pc/initcode.s - 664 sys sys 1015014519 282
 sys/src/9/pc/io.h - 664 sys sys 1165555523 9406
 sys/src/9/pc/kbd.c - 664 sys sys 1191355133 12339
-sys/src/9/pc/l.s - 664 sys sys 1190268443 29347
+sys/src/9/pc/l.s - 664 sys sys 1196193040 29691
 sys/src/9/pc/main.c - 664 sys sys 1168306227 15337
-sys/src/9/pc/mem.h - 664 sys sys 1137622431 5203
-sys/src/9/pc/memory.c - 664 sys sys 1194216046 18820
+sys/src/9/pc/mem.h - 664 sys sys 1196193040 5308
+sys/src/9/pc/memory.c - 664 sys sys 1196193039 18878
 sys/src/9/pc/mkfile - 664 sys sys 1191885521 4025
 sys/src/9/pc/mmu.c - 664 sys sys 1171688128 24591
 sys/src/9/pc/mouse.c - 664 sys sys 1098479254 7057
@@ -8211,7 +8214,7 @@ sys/src/9/port/devbridge.c - 664 sys sys 1187735844 24076
 sys/src/9/port/devcap.c - 664 sys sys 1178886040 4141
 sys/src/9/port/devcons.c - 664 sys sys 1176658321 22943
 sys/src/9/port/devdraw.c - 664 sys sys 1147023550 44447
-sys/src/9/port/devdup.c - 664 sys sys 1014931172 2332
+sys/src/9/port/devdup.c - 664 sys sys 1196185172 2327
 sys/src/9/port/devenv.c - 664 sys sys 1169498893 7015
 sys/src/9/port/devfs.c - 664 sys sys 1191279047 14902
 sys/src/9/port/devkbmap.c - 664 sys sys 1130763846 3064
@@ -13276,7 +13279,7 @@ sys/src/cmd/read.c - 664 sys sys 1022047660 1278
 sys/src/cmd/replica - 20000000775 sys sys 1053210813 0
 sys/src/cmd/replica/all.h - 664 sys sys 1091904421 1265
 sys/src/cmd/replica/applychanges.c - 664 sys sys 1155363028 6122
-sys/src/cmd/replica/applylog.c - 664 sys sys 1139667399 21874
+sys/src/cmd/replica/applylog.c - 664 sys sys 1196208729 24238
 sys/src/cmd/replica/avl.c - 664 sys sys 1068497830 6242
 sys/src/cmd/replica/compactdb.c - 664 sys sys 1018323475 652
 sys/src/cmd/replica/db.c - 664 sys sys 1019340165 2989
@@ -13297,7 +13300,7 @@ sys/src/cmd/rio/scrl.c - 664 sys sys 1014926357 3245
 sys/src/cmd/rio/time.c - 664 sys sys 1014926357 1829
 sys/src/cmd/rio/util.c - 664 sys sys 1014926357 2061
 sys/src/cmd/rio/wctl.c - 664 sys sys 1023206837 8808
-sys/src/cmd/rio/wind.c - 664 sys sys 1179591640 33382
+sys/src/cmd/rio/wind.c - 664 sys sys 1196212671 33345
 sys/src/cmd/rio/xfid.c - 664 sys sys 1103205531 17446
 sys/src/cmd/rm.c - 664 sys sys 1014926615 1563
 sys/src/cmd/rx.c - 664 sys sys 1185066370 4411
@@ -14523,6 +14526,104 @@ sys/src/games/mahjongg/mahjongg.h - 664 sys sys 1191355577 2092
 sys/src/games/mahjongg/mkfile - 664 sys sys 1191354593 241
 sys/src/games/memo.c - 664 sys sys 1130853201 6471
 sys/src/games/mkfile - 664 sys sys 1140203009 595
+sys/src/games/mp3dec - 20000000775 sys sys 1196207939 0
+sys/src/games/mp3dec/audio.c - 664 sys sys 956186249 5802
+sys/src/games/mp3dec/audio.h - 664 sys sys 956186249 2275
+sys/src/games/mp3dec/audio_dummy.c - 664 sys sys 956186347 770
+sys/src/games/mp3dec/buffer.c - 664 sys sys 956186250 4925
+sys/src/games/mp3dec/buffer.h - 664 sys sys 956186250 349
+sys/src/games/mp3dec/common.c - 664 sys sys 956186250 18447
+sys/src/games/mp3dec/common.h - 664 sys sys 956186250 459
+sys/src/games/mp3dec/control_generic.c - 664 sys sys 956186250 7166
+sys/src/games/mp3dec/dct64.c - 664 sys sys 956186250 3556
+sys/src/games/mp3dec/decode.c - 664 sys sys 956186251 4711
+sys/src/games/mp3dec/decode_2to1.c - 664 sys sys 956186251 5064
+sys/src/games/mp3dec/decode_4to1.c - 664 sys sys 956186251 5439
+sys/src/games/mp3dec/decode_ntom.c - 664 sys sys 956186251 6114
+sys/src/games/mp3dec/equalize.dat - 664 sys sys 956186251 459
+sys/src/games/mp3dec/equalizer.c - 664 sys sys 956186251 513
+sys/src/games/mp3dec/genre.h - 664 sys sys 956186251 2564
+sys/src/games/mp3dec/getbits.c - 664 sys sys 956186251 2139
+sys/src/games/mp3dec/getbits.h - 664 sys sys 956186251 1095
+sys/src/games/mp3dec/getlopt.c - 664 sys sys 956186252 2660
+sys/src/games/mp3dec/getlopt.h - 664 sys sys 956186252 1665
+sys/src/games/mp3dec/httpget.c - 664 sys sys 956186252 7340
+sys/src/games/mp3dec/huffman.h - 664 sys sys 956186252 15949
+sys/src/games/mp3dec/l2tables.h - 664 sys sys 956186252 8305
+sys/src/games/mp3dec/layer1.c - 664 sys sys 956186252 3764
+sys/src/games/mp3dec/layer2.c - 664 sys sys 956186252 8602
+sys/src/games/mp3dec/layer3.c - 664 sys sys 956186252 50154
+sys/src/games/mp3dec/mkfile - 664 sys sys 956257007 824
+sys/src/games/mp3dec/mpg123.c - 664 sys sys 956186253 33082
+sys/src/games/mp3dec/mpg123.h - 664 sys sys 956256699 9852
+sys/src/games/mp3dec/readers.c - 664 sys sys 956186253 9684
+sys/src/games/mp3dec/tabinit.c - 664 sys sys 956186253 4530
+sys/src/games/mp3dec/term.c - 664 sys sys 956186253 3534
+sys/src/games/mp3dec/term.h - 664 sys sys 956186254 949
+sys/src/games/mp3dec/version.h - 664 sys sys 956186254 74
+sys/src/games/mp3dec/wav.c - 664 sys sys 956256257 6410
+sys/src/games/mp3dec/xfermem.c - 664 sys sys 956186254 5261
+sys/src/games/mp3dec/xfermem.h - 664 sys sys 956186254 1742
+sys/src/games/mp3enc - 20000000775 sys sys 1196206922 0
+sys/src/games/mp3enc/README - 664 sys sys 986804225 1921
+sys/src/games/mp3enc/VbrTag.c - 664 sys sys 986804077 14889
+sys/src/games/mp3enc/VbrTag.h - 664 sys sys 986804077 2658
+sys/src/games/mp3enc/bitstream.c - 664 sys sys 1188006218 24525
+sys/src/games/mp3enc/bitstream.h - 664 sys sys 986804078 1350
+sys/src/games/mp3enc/brhist.h - 664 sys sys 986804356 1908
+sys/src/games/mp3enc/encoder.c - 664 sys sys 986804078 18153
+sys/src/games/mp3enc/encoder.h - 664 sys sys 986804078 3384
+sys/src/games/mp3enc/fft.c - 664 sys sys 986804078 8980
+sys/src/games/mp3enc/fft.h - 664 sys sys 986804078 1197
+sys/src/games/mp3enc/get_audio.c - 664 sys sys 1187996284 49492
+sys/src/games/mp3enc/get_audio.h - 664 sys sys 986804326 2883
+sys/src/games/mp3enc/id3tag.c - 664 sys sys 986804078 18457
+sys/src/games/mp3enc/id3tag.h - 664 sys sys 986804078 662
+sys/src/games/mp3enc/l3side.h - 664 sys sys 986804078 2304
+sys/src/games/mp3enc/lame-analysis.h - 664 sys sys 986804078 2612
+sys/src/games/mp3enc/lame.c - 664 sys sys 1188011080 55596
+sys/src/games/mp3enc/lame.h - 664 sys sys 986804049 37083
+sys/src/games/mp3enc/lameerror.h - 664 sys sys 986804078 705
+sys/src/games/mp3enc/lametime.c - 664 sys sys 1187990260 2269
+sys/src/games/mp3enc/lametime.h - 664 sys sys 986804326 1189
+sys/src/games/mp3enc/machine.h - 664 sys sys 986804078 3561
+sys/src/games/mp3enc/main.c - 664 sys sys 1187996179 7153
+sys/src/games/mp3enc/main.h - 664 sys sys 986804326 1552
+sys/src/games/mp3enc/memory.h - 664 sys sys 986804049 40
+sys/src/games/mp3enc/mkfile - 664 sys sys 1188011539 1108
+sys/src/games/mp3enc/mpglib_interface.c - 664 sys sys 986804078 4606
+sys/src/games/mp3enc/newmdct.c - 664 sys sys 986804078 32298
+sys/src/games/mp3enc/newmdct.h - 664 sys sys 986804078 1017
+sys/src/games/mp3enc/parse.c - 664 sys sys 1187991583 36701
+sys/src/games/mp3enc/parse.h - 664 sys sys 1187991011 510
+sys/src/games/mp3enc/pcm.c - 664 sys sys 986804078 53702
+sys/src/games/mp3enc/pcm.h - 664 sys sys 986804078 12026
+sys/src/games/mp3enc/portableio.c - 664 sys sys 986804036 11079
+sys/src/games/mp3enc/portableio.h - 664 sys sys 986804326 4522
+sys/src/games/mp3enc/psymodel.c - 664 sys sys 986804078 63231
+sys/src/games/mp3enc/psymodel.h - 664 sys sys 986804078 1574
+sys/src/games/mp3enc/quantize.c - 664 sys sys 986804078 59414
+sys/src/games/mp3enc/quantize.h - 664 sys sys 986804078 2638
+sys/src/games/mp3enc/quantize_pvt.c - 664 sys sys 1188007063 33737
+sys/src/games/mp3enc/quantize_pvt.h - 664 sys sys 986804078 4442
+sys/src/games/mp3enc/reservoir.c - 664 sys sys 986804078 8551
+sys/src/games/mp3enc/reservoir.h - 664 sys sys 986804078 1274
+sys/src/games/mp3enc/set_get.c - 664 sys sys 986804078 18076
+sys/src/games/mp3enc/tables.c - 664 sys sys 986804078 20176
+sys/src/games/mp3enc/tables.h - 664 sys sys 986804078 2532
+sys/src/games/mp3enc/takehiro.c - 664 sys sys 1188007347 24560
+sys/src/games/mp3enc/testcase.mp3 - 664 sys sys 986804498 9591
+sys/src/games/mp3enc/testcase.wav - 664 sys sys 986803994 100044
+sys/src/games/mp3enc/timestatus.c - 664 sys sys 986804036 7350
+sys/src/games/mp3enc/timestatus.h - 664 sys sys 986804326 1286
+sys/src/games/mp3enc/tools.c - 664 sys sys 986804078 233
+sys/src/games/mp3enc/tools.h - 664 sys sys 986804078 0
+sys/src/games/mp3enc/util.c - 664 sys sys 986804078 23561
+sys/src/games/mp3enc/util.h - 664 sys sys 1188007745 17081
+sys/src/games/mp3enc/vbrquantize.c - 664 sys sys 986804078 49531
+sys/src/games/mp3enc/version.c - 664 sys sys 986804078 5852
+sys/src/games/mp3enc/version.h - 664 sys sys 986804078 2416
+sys/src/games/mp3enc/vorbis_interface.c - 664 sys sys 986804078 16761
 sys/src/games/music - 20000000775 sys sys 1103793915 0
 sys/src/games/music/Readme - 664 sys sys 1103793914 488
 sys/src/games/music/debug.h - 664 sys sys 1103793914 201
@@ -15207,9 +15308,9 @@ sys/src/libflate/zlib.h - 664 sys sys 984709217 219
 sys/src/libframe - 20000000775 sys sys 1039727690 0
 sys/src/libframe/frbox.c - 664 sys sys 1078466650 3028
 sys/src/libframe/frdelete.c - 664 sys sys 944961726 3079
-sys/src/libframe/frdraw.c - 664 sys sys 1147706378 3447
+sys/src/libframe/frdraw.c - 664 sys sys 1196212624 3990
 sys/src/libframe/frinit.c - 664 sys sys 1019498851 1761
-sys/src/libframe/frinsert.c - 664 sys sys 1147706378 6720
+sys/src/libframe/frinsert.c - 664 sys sys 1196212625 6722
 sys/src/libframe/frptofchar.c - 664 sys sys 944961726 1995
 sys/src/libframe/frselect.c - 664 sys sys 1021580002 2623
 sys/src/libframe/frstr.c - 664 sys sys 944961726 646
@@ -15747,3 +15848,4 @@ usr/glenda/lib/profile - 664 glenda glenda 1105128663 890
 usr/glenda/readme.acme - 664 glenda glenda 1019860628 4753
 usr/glenda/readme.rio - 664 glenda glenda 1019860628 6370
 usr/glenda/tmp - 20000000775 glenda glenda 1018802620 0
+386/bin/games/mp3dec - 775 sys sys 1196207154 355822

+ 111 - 10
dist/replica/plan9.db

@@ -260,6 +260,8 @@
 386/bin/games/jukefs - 775 sys sys 1105589129 165320
 386/bin/games/mahjongg - 775 sys sys 1191381911 165242
 386/bin/games/memo - 775 sys sys 1179372089 156656
+386/bin/games/mp3dec - 775 sys sys 1196207154 355822
+386/bin/games/mp3enc - 775 sys sys 1196220182 530357
 386/bin/games/playlistfs - 775 sys sys 1105589129 148484
 386/bin/games/sokoban - 775 sys sys 1179372090 165514
 386/bin/games/sudoku - 775 sys sys 1179372090 171015
@@ -5244,7 +5246,7 @@ lib/namespace - 664 sys sys 1176262168 619
 lib/namespace.ftp - 664 sys sys 1020313578 373
 lib/namespace.httpd - 664 sys sys 984695868 1209
 lib/ndb - 20000000775 sys sys 1065569740 0
-lib/ndb/auth - 664 sys sys 1117108784 572
+lib/ndb/auth - 664 sys sys 1196183272 571
 lib/ndb/common - 664 sys sys 1133553666 5376
 lib/ndb/consoledb - 664 sys sys 960222421 95
 lib/ndb/dhcp - 20000000775 sys sys 1020895764 0
@@ -6092,7 +6094,7 @@ sys/include/draw.h - 664 sys sys 1108655526 16144
 sys/include/event.h - 664 sys sys 1014929063 1426
 sys/include/fcall.h - 664 sys sys 1137461445 3063
 sys/include/flate.h - 664 sys sys 1014929063 1245
-sys/include/frame.h - 664 sys sys 1147706379 2682
+sys/include/frame.h - 664 sys sys 1196212617 2708
 sys/include/geometry.h - 664 sys sys 1014929063 2632
 sys/include/html.h - 664 sys sys 1184472600 15622
 sys/include/httpd.h - 664 sys sys 1190835025 5800
@@ -7428,6 +7430,7 @@ sys/man/1/mc - 664 sys sys 1113743326 552
 sys/man/1/mk - 664 sys sys 1113743328 13198
 sys/man/1/mkdir - 664 sys sys 1082593141 717
 sys/man/1/mlmgr - 664 sys sys 1116513886 2542
+sys/man/1/mp3enc - 664 sys sys 1196208904 3236
 sys/man/1/ms2html - 664 sys sys 1138458899 1252
 sys/man/1/mug - 664 sys sys 1158800370 1424
 sys/man/1/nedmail - 664 sys sys 1159419884 6821
@@ -8120,10 +8123,10 @@ sys/src/9/pc/init9.c - 664 sys sys 1040002518 94
 sys/src/9/pc/initcode.s - 664 sys sys 1015014519 282
 sys/src/9/pc/io.h - 664 sys sys 1165555523 9406
 sys/src/9/pc/kbd.c - 664 sys sys 1191355133 12339
-sys/src/9/pc/l.s - 664 sys sys 1190268443 29347
+sys/src/9/pc/l.s - 664 sys sys 1196193040 29691
 sys/src/9/pc/main.c - 664 sys sys 1168306227 15337
-sys/src/9/pc/mem.h - 664 sys sys 1137622431 5203
-sys/src/9/pc/memory.c - 664 sys sys 1194216046 18820
+sys/src/9/pc/mem.h - 664 sys sys 1196193040 5308
+sys/src/9/pc/memory.c - 664 sys sys 1196193039 18878
 sys/src/9/pc/mkfile - 664 sys sys 1191885521 4025
 sys/src/9/pc/mmu.c - 664 sys sys 1171688128 24591
 sys/src/9/pc/mouse.c - 664 sys sys 1098479254 7057
@@ -8211,7 +8214,7 @@ sys/src/9/port/devbridge.c - 664 sys sys 1187735844 24076
 sys/src/9/port/devcap.c - 664 sys sys 1178886040 4141
 sys/src/9/port/devcons.c - 664 sys sys 1176658321 22943
 sys/src/9/port/devdraw.c - 664 sys sys 1147023550 44447
-sys/src/9/port/devdup.c - 664 sys sys 1014931172 2332
+sys/src/9/port/devdup.c - 664 sys sys 1196185172 2327
 sys/src/9/port/devenv.c - 664 sys sys 1169498893 7015
 sys/src/9/port/devfs.c - 664 sys sys 1191279047 14902
 sys/src/9/port/devkbmap.c - 664 sys sys 1130763846 3064
@@ -13276,7 +13279,7 @@ sys/src/cmd/read.c - 664 sys sys 1022047660 1278
 sys/src/cmd/replica - 20000000775 sys sys 1053210813 0
 sys/src/cmd/replica/all.h - 664 sys sys 1091904421 1265
 sys/src/cmd/replica/applychanges.c - 664 sys sys 1155363028 6122
-sys/src/cmd/replica/applylog.c - 664 sys sys 1139667399 21874
+sys/src/cmd/replica/applylog.c - 664 sys sys 1196208729 24238
 sys/src/cmd/replica/avl.c - 664 sys sys 1068497830 6242
 sys/src/cmd/replica/compactdb.c - 664 sys sys 1018323475 652
 sys/src/cmd/replica/db.c - 664 sys sys 1019340165 2989
@@ -13297,7 +13300,7 @@ sys/src/cmd/rio/scrl.c - 664 sys sys 1014926357 3245
 sys/src/cmd/rio/time.c - 664 sys sys 1014926357 1829
 sys/src/cmd/rio/util.c - 664 sys sys 1014926357 2061
 sys/src/cmd/rio/wctl.c - 664 sys sys 1023206837 8808
-sys/src/cmd/rio/wind.c - 664 sys sys 1179591640 33382
+sys/src/cmd/rio/wind.c - 664 sys sys 1196212671 33345
 sys/src/cmd/rio/xfid.c - 664 sys sys 1103205531 17446
 sys/src/cmd/rm.c - 664 sys sys 1014926615 1563
 sys/src/cmd/rx.c - 664 sys sys 1185066370 4411
@@ -14523,6 +14526,104 @@ sys/src/games/mahjongg/mahjongg.h - 664 sys sys 1191355577 2092
 sys/src/games/mahjongg/mkfile - 664 sys sys 1191354593 241
 sys/src/games/memo.c - 664 sys sys 1130853201 6471
 sys/src/games/mkfile - 664 sys sys 1140203009 595
+sys/src/games/mp3dec - 20000000775 sys sys 1196207939 0
+sys/src/games/mp3dec/audio.c - 664 sys sys 956186249 5802
+sys/src/games/mp3dec/audio.h - 664 sys sys 956186249 2275
+sys/src/games/mp3dec/audio_dummy.c - 664 sys sys 956186347 770
+sys/src/games/mp3dec/buffer.c - 664 sys sys 956186250 4925
+sys/src/games/mp3dec/buffer.h - 664 sys sys 956186250 349
+sys/src/games/mp3dec/common.c - 664 sys sys 956186250 18447
+sys/src/games/mp3dec/common.h - 664 sys sys 956186250 459
+sys/src/games/mp3dec/control_generic.c - 664 sys sys 956186250 7166
+sys/src/games/mp3dec/dct64.c - 664 sys sys 956186250 3556
+sys/src/games/mp3dec/decode.c - 664 sys sys 956186251 4711
+sys/src/games/mp3dec/decode_2to1.c - 664 sys sys 956186251 5064
+sys/src/games/mp3dec/decode_4to1.c - 664 sys sys 956186251 5439
+sys/src/games/mp3dec/decode_ntom.c - 664 sys sys 956186251 6114
+sys/src/games/mp3dec/equalize.dat - 664 sys sys 956186251 459
+sys/src/games/mp3dec/equalizer.c - 664 sys sys 956186251 513
+sys/src/games/mp3dec/genre.h - 664 sys sys 956186251 2564
+sys/src/games/mp3dec/getbits.c - 664 sys sys 956186251 2139
+sys/src/games/mp3dec/getbits.h - 664 sys sys 956186251 1095
+sys/src/games/mp3dec/getlopt.c - 664 sys sys 956186252 2660
+sys/src/games/mp3dec/getlopt.h - 664 sys sys 956186252 1665
+sys/src/games/mp3dec/httpget.c - 664 sys sys 956186252 7340
+sys/src/games/mp3dec/huffman.h - 664 sys sys 956186252 15949
+sys/src/games/mp3dec/l2tables.h - 664 sys sys 956186252 8305
+sys/src/games/mp3dec/layer1.c - 664 sys sys 956186252 3764
+sys/src/games/mp3dec/layer2.c - 664 sys sys 956186252 8602
+sys/src/games/mp3dec/layer3.c - 664 sys sys 956186252 50154
+sys/src/games/mp3dec/mkfile - 664 sys sys 956257007 824
+sys/src/games/mp3dec/mpg123.c - 664 sys sys 956186253 33082
+sys/src/games/mp3dec/mpg123.h - 664 sys sys 956256699 9852
+sys/src/games/mp3dec/readers.c - 664 sys sys 956186253 9684
+sys/src/games/mp3dec/tabinit.c - 664 sys sys 956186253 4530
+sys/src/games/mp3dec/term.c - 664 sys sys 956186253 3534
+sys/src/games/mp3dec/term.h - 664 sys sys 956186254 949
+sys/src/games/mp3dec/version.h - 664 sys sys 956186254 74
+sys/src/games/mp3dec/wav.c - 664 sys sys 956256257 6410
+sys/src/games/mp3dec/xfermem.c - 664 sys sys 956186254 5261
+sys/src/games/mp3dec/xfermem.h - 664 sys sys 956186254 1742
+sys/src/games/mp3enc - 20000000775 sys sys 1196206922 0
+sys/src/games/mp3enc/README - 664 sys sys 986804225 1921
+sys/src/games/mp3enc/VbrTag.c - 664 sys sys 986804077 14889
+sys/src/games/mp3enc/VbrTag.h - 664 sys sys 986804077 2658
+sys/src/games/mp3enc/bitstream.c - 664 sys sys 1188006218 24525
+sys/src/games/mp3enc/bitstream.h - 664 sys sys 986804078 1350
+sys/src/games/mp3enc/brhist.h - 664 sys sys 986804356 1908
+sys/src/games/mp3enc/encoder.c - 664 sys sys 986804078 18153
+sys/src/games/mp3enc/encoder.h - 664 sys sys 986804078 3384
+sys/src/games/mp3enc/fft.c - 664 sys sys 986804078 8980
+sys/src/games/mp3enc/fft.h - 664 sys sys 986804078 1197
+sys/src/games/mp3enc/get_audio.c - 664 sys sys 1187996284 49492
+sys/src/games/mp3enc/get_audio.h - 664 sys sys 986804326 2883
+sys/src/games/mp3enc/id3tag.c - 664 sys sys 986804078 18457
+sys/src/games/mp3enc/id3tag.h - 664 sys sys 986804078 662
+sys/src/games/mp3enc/l3side.h - 664 sys sys 986804078 2304
+sys/src/games/mp3enc/lame-analysis.h - 664 sys sys 986804078 2612
+sys/src/games/mp3enc/lame.c - 664 sys sys 1188011080 55596
+sys/src/games/mp3enc/lame.h - 664 sys sys 986804049 37083
+sys/src/games/mp3enc/lameerror.h - 664 sys sys 986804078 705
+sys/src/games/mp3enc/lametime.c - 664 sys sys 1187990260 2269
+sys/src/games/mp3enc/lametime.h - 664 sys sys 986804326 1189
+sys/src/games/mp3enc/machine.h - 664 sys sys 986804078 3561
+sys/src/games/mp3enc/main.c - 664 sys sys 1187996179 7153
+sys/src/games/mp3enc/main.h - 664 sys sys 986804326 1552
+sys/src/games/mp3enc/memory.h - 664 sys sys 986804049 40
+sys/src/games/mp3enc/mkfile - 664 sys sys 1188011539 1108
+sys/src/games/mp3enc/mpglib_interface.c - 664 sys sys 986804078 4606
+sys/src/games/mp3enc/newmdct.c - 664 sys sys 986804078 32298
+sys/src/games/mp3enc/newmdct.h - 664 sys sys 986804078 1017
+sys/src/games/mp3enc/parse.c - 664 sys sys 1187991583 36701
+sys/src/games/mp3enc/parse.h - 664 sys sys 1187991011 510
+sys/src/games/mp3enc/pcm.c - 664 sys sys 986804078 53702
+sys/src/games/mp3enc/pcm.h - 664 sys sys 986804078 12026
+sys/src/games/mp3enc/portableio.c - 664 sys sys 986804036 11079
+sys/src/games/mp3enc/portableio.h - 664 sys sys 986804326 4522
+sys/src/games/mp3enc/psymodel.c - 664 sys sys 986804078 63231
+sys/src/games/mp3enc/psymodel.h - 664 sys sys 986804078 1574
+sys/src/games/mp3enc/quantize.c - 664 sys sys 986804078 59414
+sys/src/games/mp3enc/quantize.h - 664 sys sys 986804078 2638
+sys/src/games/mp3enc/quantize_pvt.c - 664 sys sys 1188007063 33737
+sys/src/games/mp3enc/quantize_pvt.h - 664 sys sys 986804078 4442
+sys/src/games/mp3enc/reservoir.c - 664 sys sys 986804078 8551
+sys/src/games/mp3enc/reservoir.h - 664 sys sys 986804078 1274
+sys/src/games/mp3enc/set_get.c - 664 sys sys 986804078 18076
+sys/src/games/mp3enc/tables.c - 664 sys sys 986804078 20176
+sys/src/games/mp3enc/tables.h - 664 sys sys 986804078 2532
+sys/src/games/mp3enc/takehiro.c - 664 sys sys 1188007347 24560
+sys/src/games/mp3enc/testcase.mp3 - 664 sys sys 986804498 9591
+sys/src/games/mp3enc/testcase.wav - 664 sys sys 986803994 100044
+sys/src/games/mp3enc/timestatus.c - 664 sys sys 986804036 7350
+sys/src/games/mp3enc/timestatus.h - 664 sys sys 986804326 1286
+sys/src/games/mp3enc/tools.c - 664 sys sys 986804078 233
+sys/src/games/mp3enc/tools.h - 664 sys sys 986804078 0
+sys/src/games/mp3enc/util.c - 664 sys sys 986804078 23561
+sys/src/games/mp3enc/util.h - 664 sys sys 1188007745 17081
+sys/src/games/mp3enc/vbrquantize.c - 664 sys sys 986804078 49531
+sys/src/games/mp3enc/version.c - 664 sys sys 986804078 5852
+sys/src/games/mp3enc/version.h - 664 sys sys 986804078 2416
+sys/src/games/mp3enc/vorbis_interface.c - 664 sys sys 986804078 16761
 sys/src/games/music - 20000000775 sys sys 1103793915 0
 sys/src/games/music/Readme - 664 sys sys 1103793914 488
 sys/src/games/music/debug.h - 664 sys sys 1103793914 201
@@ -15207,9 +15308,9 @@ sys/src/libflate/zlib.h - 664 sys sys 984709217 219
 sys/src/libframe - 20000000775 sys sys 1039727690 0
 sys/src/libframe/frbox.c - 664 sys sys 1078466650 3028
 sys/src/libframe/frdelete.c - 664 sys sys 944961726 3079
-sys/src/libframe/frdraw.c - 664 sys sys 1147706378 3447
+sys/src/libframe/frdraw.c - 664 sys sys 1196212624 3990
 sys/src/libframe/frinit.c - 664 sys sys 1019498851 1761
-sys/src/libframe/frinsert.c - 664 sys sys 1147706378 6720
+sys/src/libframe/frinsert.c - 664 sys sys 1196212625 6722
 sys/src/libframe/frptofchar.c - 664 sys sys 944961726 1995
 sys/src/libframe/frselect.c - 664 sys sys 1021580002 2623
 sys/src/libframe/frstr.c - 664 sys sys 944961726 646

File diff suppressed because it is too large
+ 17494 - 55716
dist/replica/plan9.log


+ 1 - 1
lib/ndb/auth

@@ -3,7 +3,7 @@
 #           server.  The attribute types used by the AS are hostid and
 #           uid.  The value in the hostid is a client host's ID.  The
 #           values in the uid pairs in the same entry list which users
-#           that host ID make speak for.  A uid value of * means the
+#           that host ID may speak for.  A uid value of * means the
 #           host ID may speak for all users.  A uid value of !user means
 #           the host ID may not speak for user.  For example:
 #           hostid=bootes

+ 3 - 2
sys/include/frame.h

@@ -58,7 +58,7 @@ void	frinsert(Frame*, Rune*, Rune*, ulong);
 void	frselect(Frame*, Mousectl*);
 void	frselectpaint(Frame*, Point, Point, Image*);
 void	frdrawsel(Frame*, Point, ulong, ulong, int);
-void	frdrawsel0(Frame*, Point, ulong, ulong, Image*, Image*);
+Point frdrawsel0(Frame*, Point, ulong, ulong, Image*, Image*);
 void	frinit(Frame*, Rectangle, Font*, Image*, Image**);
 void	frsetrects(Frame*, Rectangle, Image*);
 void	frclear(Frame*, int);
@@ -80,13 +80,14 @@ void	_fradvance(Frame*, Point*, Frbox*);
 int	_frnewwid(Frame*, Point, Frbox*);
 int	_frnewwid0(Frame*, Point, Frbox*);
 void	_frclean(Frame*, Point, int, int);
-void	_frredraw(Frame*, Point, Image*, Image*);
+void	_frdrawtext(Frame*, Point, Image*, Image*);
 void	_fraddbox(Frame*, int, int);
 Point	_frptofcharptb(Frame*, ulong, Point, int);
 Point	_frptofcharnb(Frame*, ulong, int);
 int	_frstrlen(Frame*, int);
 void	frtick(Frame*, Point, int);
 void	frinittick(Frame*);
+void	frredraw(Frame*);
 
 #define	NRUNE(b)	((b)->nrune<0? 1 : (b)->nrune)
 #define	NBYTE(b)	strlen((char*)(b)->ptr)

BIN
sys/lib/music/icon/cross.bit


BIN
sys/lib/music/icon/down.bit


BIN
sys/lib/music/icon/exit.bit


BIN
sys/lib/music/icon/grey.bit


BIN
sys/lib/music/icon/minus.bit


BIN
sys/lib/music/icon/next.bit


BIN
sys/lib/music/icon/pause.bit


BIN
sys/lib/music/icon/play.bit


BIN
sys/lib/music/icon/prev.bit


BIN
sys/lib/music/icon/question.bit


BIN
sys/lib/music/icon/root.bit


BIN
sys/lib/music/icon/select.bit


BIN
sys/lib/music/icon/skull.bit


BIN
sys/lib/music/icon/stop.bit


BIN
sys/lib/music/icon/trash.bit


BIN
sys/lib/music/icon/up.bit


BIN
sys/lib/music/icon/volume.bit


+ 209 - 0
sys/man/1/mp3enc

@@ -0,0 +1,209 @@
+.TH MP3ENC 1
+.SH NAME
+mp3enc \- create mp3 audio files
+.SH SYNOPSIS
+.in +0.5i
+.ti -0.5i
+.B games/mp3enc
+[
+.B -hprv
+] [
+.B -b
+.I bitrate
+] [
+.B -B
+.I bitrate
+] [
+.B -m
+.I mode
+] [
+.B -q
+q ] [
+.B -s
+.I sfreq
+] [
+.B -V
+.I q
+] [
+.I "long or silly options"
+]
+.in -0.5i
+.SH DESCRIPTION
+.I Mp3enc
+compresses audio on standard input,
+normally PCM-encoded,
+and produces MP3-encoded audio on standard output.
+By default, the MP3 file will use `constant bit-rate' (CBR)
+encoding, but that can be changed via
+.B --abr
+(average bitrate desired, ABR)
+or
+.BR -v
+(variable bitrate, VBR).
+.SS Options
+.TF "\fB-b \fP"
+.TP
+.B -b
+set minimum allowed
+.I bitrate
+in Kb/s for VBR, default 32Kb/s.
+For CBR,
+set the exact bitrate in Kb/s, which defaults to 128Kb/s.
+.TP
+.B -B
+set maximum allowed
+.I bitrate
+in Kb/s for VBR, default 256Kb/s.
+.TP
+.BI -h
+same as
+.LR "-q 2" .
+.TP
+.B -m
+.I mode
+may be
+(s)tereo,
+(j)oint,
+(f)orce
+or
+(m)ono
+(default j).
+.B force
+forces mid/side stereo on all frames.
+.TP
+.B -p
+add CRC error protection (adds an additional 16 bits per frame to the stream).
+This seems to break playback.
+.TP
+.B -q
+sets output quality to
+.I q
+(see
+.BR -V ).
+.TP
+.B -r
+input is raw pcm
+.TP
+.B -s
+set sampling frequency of input file (in KHz) to
+.IR sfreq ,
+default is 44.1.
+.TP
+.B -v
+use variable bitrate (VBR) encoding
+.TP
+.B -V
+set quality setting for VBR to
+.IR q .
+Default
+.I q
+is 4;
+0 produces highest-quality and largest files, and
+9 produces lowest-quality and smallest files.
+.SS Long options
+.TF "\fB--resample sfreq \fP"
+.TP
+.BI --abr " bitrate"
+sets average
+.I bitrate
+desired in Kb/s, instead of setting quality,
+and generates ABR encoding.
+.TP
+.BI --resample " sfreq"
+set sampling frequency of output file (in KHz) to
+.IR sfreq ,
+default is input sfreq.
+.TP
+.BI --mp3input
+.I input
+is an MP3 file
+.
+.SS Silly options
+.TF --nohist
+.TP
+.BI -f
+same as
+.LR "-q 7" .
+Such a deal. 
+.TP
+.BI -o
+mark as non-original (i.e. do not set the original bit)
+.TP
+.BI -c
+mark as copyright
+.TP
+.BI -k
+disable sfb=21 cutoff
+.TP
+.BI -e " emp"
+de-emphasis n/5/c
+(default n)
+.TP
+.BI -d
+allow channels to have different blocktypes
+.TP
+.BI -t
+disable Xing VBR informational tag
+.TP
+.BI -a
+autoconvert from stereo to mono file for mono encoding
+.TP
+.BI -x
+force byte-swapping of input (see
+.IR dd (1)
+instead)
+.TP
+.BI -S
+don't print progress report, VBR histograms
+.TP
+.BI --athonly
+only use the ATH for masking
+.TP
+.BI --nohist
+disable VBR histogram display
+.TP
+.BI --voice
+experimental voice mode
+.
+.SH EXAMPLES
+Encode a
+.L .wav
+file as highest-quality MP3.
+.IP
+.EX
+games/mp3enc -q 0 -b 320
+.EE
+.LP
+Create a fixed 128Kb/s MP3 file from a
+.L .wav
+file.
+.IP
+.EX
+games/mp3enc -h <foo.wav >foo.mp3
+.EE
+.LP
+Streaming from stereo 44.1KHz raw PCM data, encoding mono at 16KHz
+(you may not need
+.IR dd ):
+.IP
+.EX
+dd -conv swab | games/mp3enc -a -r -m m --resample 16 -b 24
+.EE
+.SH BUGS
+Quality is much better than encoders based on the ISO routines,
+but still not as good as the FhG encoder.
+.PP
+It's a GNU behemoth, lightly rehabilitated.
+There are zillions of undocumented options.
+.SH SOURCE
+.B /sys/src/games/mp3enc
+.SH SEE ALSO
+.IR dd (1),
+.IR mp3dec (1),
+.IR audio (3),
+.IR cdfs (4),
+.IR audio (7),
+.IR juke (7),
+.IR playlistfs (7)
+.br
+.B http://www.sulaco.org/mp3

+ 25 - 8
sys/src/9/pc/l.s

@@ -53,15 +53,19 @@ TEXT _multibootheader(SB), $0
 	LONG	$0				/* depth */
 
 /*
- * In protected mode with paging turned off and segment registers setup to linear map all memory.
- * Entered via a jump to PADDR(entry), the physical address of the virtual kernel entry point of KADDR(entry)
- * Make the basic page tables for processor 0. Four pages are needed for the basic set:
- * a page directory, a page table for mapping the first 4MB of physical memory to KZERO,
- * and virtual and physical pages for mapping the Mach structure.
+ * In protected mode with paging turned off and segment registers setup
+ * to linear map all memory. Entered via a jump to PADDR(entry),
+ * the physical address of the virtual kernel entry point of KADDR(entry).
+ * Make the basic page tables for processor 0. Six pages are needed for
+ * the basic set:
+ *	a page directory;
+ *	page tables for mapping the first 8MB of physical memory to KZERO;
+ *	a page for the GDT;
+ *	virtual and physical pages for mapping the Mach structure.
  * The remaining PTEs will be allocated later when memory is sized.
- * An identity mmu map is also needed for the switch to virtual mode.  This
- * identity mapping is removed once the MMU is going and the JMP has been made
- * to virtual memory.
+ * An identity mmu map is also needed for the switch to virtual mode.
+ * This identity mapping is removed once the MMU is going and the JMP has
+ * been made to virtual memory.
  */
 TEXT _startPADDR(SB), $0
 	CLI					/* make sure interrupts are off */
@@ -144,6 +148,11 @@ TEXT mode32bit(SB), $0
 	MOVL	$(PTEWRITE|PTEVALID), BX	/* page permissions */
 	ORL	BX, (AX)
 
+	ADDL	$4, AX
+	MOVL	$PADDR(CPU0PTE1), (AX)		/* PTE's for KZERO+4MB */
+	MOVL	$(PTEWRITE|PTEVALID), BX	/* page permissions */
+	ORL	BX, (AX)
+
 	MOVL	$PADDR(CPU0PTE), AX		/* first page of page table */
 	MOVL	$1024, CX			/* 1024 pages in 4MB */
 _setpte:
@@ -152,6 +161,14 @@ _setpte:
 	ADDL	$4, AX
 	LOOP	_setpte
 
+	MOVL	$PADDR(CPU0PTE1), AX		/* second page of page table */
+	MOVL	$1024, CX			/* 1024 pages in 4MB */
+_setpte1:
+	MOVL	BX, (AX)
+	ADDL	$(1<<PGSHIFT), BX
+	ADDL	$4, AX
+	LOOP	_setpte1
+
 	MOVL	$PADDR(CPU0PTE), AX
 	ADDL	$PTO(MACHADDR), AX		/* page table entry offset for MACHADDR */
 	MOVL	$PADDR(CPU0MACH), (AX)		/* PTE for Mach */

+ 4 - 2
sys/src/9/pc/mem.h

@@ -63,10 +63,12 @@
 #define	MACHADDR	(KZERO+0x15000)		/* as seen by current processor */
 #define	CPU0MACH	(KZERO+0x16000)		/* Mach for bootstrap processor */
 #define	MACHSIZE	BY2PG
+#define CPU0PTE1	(KZERO+0x17000)		/* bootstrap processor PTE's for 4MB-8MB */
+#define CPU0END		(CPU0PTE1+BY2PG)
 /*
- * N.B.  ramscan knows that CPU0MACH+BY2PG is the end of reserved data
+ * N.B.  ramscan knows that CPU0END is the end of reserved data
  * N.B.  _startPADDR knows that CPU0PDB is the first reserved page
- * and that there are 5 of them.
+ * and that there are 6 of them.
  */
 
 /*

+ 29 - 26
sys/src/9/pc/memory.c

@@ -1,6 +1,9 @@
 /*
  * Size memory and create the kernel page-tables on the fly while doing so.
  * Called from main(), this code should only be run by the bootstrap processor.
+ *
+ * MemMin is what the bootstrap code in l.s has already mapped;
+ * MemMax is the limit of physical memory to scan.
  */
 #include "u.h"
 #include "../port/lib.h"
@@ -21,10 +24,8 @@ enum {
 
 	KB		= 1024,
 
-	MemMinMB	= 4,		/* minimum physical memory (<=4MB) */
-	MemMaxMB	= 3*1024+768,	/* maximum physical memory to check */
-
-	NMemBase	= 10,
+	MemMin		= 8*MB,
+	MemMax		= (3*1024+768)*MB,
 };
 
 typedef struct Map Map;
@@ -331,14 +332,16 @@ lowraminit(void)
 	 * bootstrap processor MMU information and the limit is obtained from
 	 * the BIOS data area.
 	 */
-	x = PADDR(CPU0MACH+BY2PG);
+	x = PADDR(CPU0END);
 	bda = (uchar*)KADDR(0x400);
 	n = ((bda[0x14]<<8)|bda[0x13])*KB-x;
 	mapfree(&rmapram, x, n);
 	memset(KADDR(x), 0, n);			/* keep us honest */
 
 	x = PADDR(PGROUND((ulong)end));
-	pa = MemMinMB*MB;
+	pa = MemMin;
+	if(x > pa)
+		panic("kernel too big");
 	mapfree(&rmapram, x, pa-x);
 	memset(KADDR(x), 0, pa-x);		/* keep us honest */
 }
@@ -351,11 +354,11 @@ ramscan(ulong maxmem)
 
 	/*
 	 * The bootstrap code has has created a prototype page
-	 * table which maps the first MemMinMB of physical memory to KZERO.
+	 * table which maps the first MemMin of physical memory to KZERO.
 	 * The page directory is at m->pdb and the first page of
 	 * free memory is after the per-processor MMU information.
 	 */
-	pa = MemMinMB*MB;
+	pa = MemMin;
 
 	/*
 	 * Check if the extended memory size can be obtained from the CMOS.
@@ -368,7 +371,7 @@ ramscan(ulong maxmem)
 	if(maxmem == 0){
 		x = (nvramread(0x18)<<8)|nvramread(0x17);
 		if(x == 0 || x >= (63*KB))
-			maxpa = MemMaxMB*MB;
+			maxpa = MemMax;
 		else
 			maxpa = MB+x*KB;
 		if(maxpa < 24*MB)
@@ -378,7 +381,7 @@ ramscan(ulong maxmem)
 	maxkpa = (u32int)-KZERO;	/* 2^32 - KZERO */
 
 	/*
-	 * March up memory from MemMinMB to maxpa 1MB at a time,
+	 * March up memory from MemMin to maxpa 1MB at a time,
 	 * mapping the first page and checking the page can
 	 * be written and read correctly. The page tables are created here
 	 * on the fly, allocating from low memory as necessary.
@@ -391,11 +394,11 @@ ramscan(ulong maxmem)
 	
 	/*
 	 * Can't map memory to KADDR(pa) when we're walking because
-	 * can only use KADDR for relatively low addresses.  Instead,
-	 * map each 4MB we scan to the virtual address range 4MB-8MB
-	 * while we are scanning.
+	 * can only use KADDR for relatively low addresses.
+	 * Instead, map each 4MB we scan to the virtual address range
+	 * MemMin->MemMin+4MB while we are scanning.
 	 */
-	vbase = 4*MB;
+	vbase = MemMin;
 	while(pa < maxpa){
 		/*
 		 * Map the page. Use mapalloc(&rmapram, ...) to make
@@ -562,18 +565,18 @@ map(ulong base, ulong len, int type)
 	ulong *table, flags, maxkpa;
 	
 	/*
-	 * Split any call crossing 4*MB to make below simpler.
+	 * Split any call crossing MemMin to make below simpler.
 	 */
-	if(base < 4*MB && len > 4*MB-base){
-		n = 4*MB - base;
+	if(base < MemMin && len > MemMin-base){
+		n = MemMin - base;
 		map(base, n, type);
-		map(4*MB, len-n, type);
+		map(MemMin, len-n, type);
 	}
 	
 	/*
-	 * Let lowraminit and umbscan hash out the low 4MB.
+	 * Let lowraminit and umbscan hash out the low MemMin.
 	 */
-	if(base < 4*MB)
+	if(base < MemMin)
 		return;
 
 	/*
@@ -586,14 +589,14 @@ map(ulong base, ulong len, int type)
 	}
 	
 	/*
-	 * Memory below CPU0MACH is reserved for the kernel
+	 * Memory below CPU0END is reserved for the kernel
 	 * and already mapped.
 	 */
-	if(base < PADDR(CPU0MACH)+BY2PG){
-		n = PADDR(CPU0MACH)+BY2PG - base;
+	if(base < PADDR(CPU0END)){
+		n = PADDR(CPU0END) - base;
 		if(len <= n)
 			return;
-		map(PADDR(CPU0MACH), len-n, type);
+		map(PADDR(CPU0END), len-n, type);
 		return;
 	}
 	
@@ -637,10 +640,10 @@ map(ulong base, ulong len, int type)
 	}
 	
 	/*
-	 * bottom 4MB is already mapped - just twiddle flags.
+	 * bottom MemMin is already mapped - just twiddle flags.
 	 * (not currently used - see above)
 	 */
-	if(base < 4*MB){
+	if(base < MemMin){
 		table = KADDR(PPN(m->pdb[PDX(base)]));
 		e = base+len;
 		base = PPN(base);

+ 1 - 1
sys/src/9/port/devdup.c

@@ -120,7 +120,7 @@ dupread(Chan *c, void *va, long n, vlong offset)
 static long
 dupwrite(Chan*, void*, long, vlong)
 {
-	panic("dupwrite");
+	error(Eperm);
 	return 0;		/* not reached */
 }
 

+ 123 - 9
sys/src/cmd/replica/applylog.c

@@ -18,7 +18,6 @@ vlong	off;
 int errors;
 int nconf;
 int donothing;
-char **conf;
 int verbose;
 char **match;
 int nmatch;
@@ -37,6 +36,7 @@ ulong maxnow;
 int maxn;
 char *timefile;
 int timefd;
+int samecontents(char*, char*);
 
 Db *copyerr;
 
@@ -288,6 +288,8 @@ main(int argc, char **argv)
 			delce(local);
 			if(!havelocal)	/* doesn't exist; who cares? */
 				break;
+			if(access(remote, AEXIST) >= 0)	/* got recreated! */
+				break;
 			if(!ismatch(name)){
 				if(!skip)
 					fprint(2, "stopped updating log apply time because of %s\n", name);
@@ -307,6 +309,10 @@ main(int argc, char **argv)
 			assert(havelocal && havedb);
 			if(dbd.mtime > rd.mtime)		/* we have a newer file than what was deleted */
 				break;
+			if(samecontents(local, remote) > 0){	/* going to get recreated */
+				chat("= %q %luo %q %q %lud\n", name, rd.mode, rd.uid, rd.gid, rd.mtime);
+				break;
+			}
 			if(!(dbd.mode&DMDIR) && (dbd.mtime != ld.mtime || dbd.length != ld.length)){	/* locally modified since we downloaded it */
 				if(resolve1 == 's')
 					goto DoRemove;
@@ -319,11 +325,11 @@ main(int argc, char **argv)
 		    DoRemove:
 			USED(checkedmatch1);
 			assert(ismatch(name));
-			chat("d %q\n", name);
+			chat("a %q %luo %q %q %lud\n", name, rd.mode, rd.uid, rd.gid, rd.mtime);
 			if(donothing)
 				break;
 			if(remove(local) < 0){
-				error("removing %q", name);
+				error("removing %q: %r", name);
 				skip = 1;
 				continue;
 			}
@@ -346,6 +352,10 @@ main(int argc, char **argv)
 					goto DoCreate;
 				if((ld.mode&DMDIR) && (rd.mode&DMDIR))
 					break;
+				if(samecontents(local, remote) > 0){
+					chat("= %q %luo %q %q %lud\n", name, rd.mode, rd.uid, rd.gid, rd.mtime);
+					goto DoCreateDb;
+				}
 				if(resolve1 == 's')
 					goto DoCreate;
 				else if(resolve1 == 'c')
@@ -367,6 +377,10 @@ main(int argc, char **argv)
 					continue;
 				}
 				SET(checkedmatch2);
+				if(samecontents(local, remote) > 0){
+					chat("= %q %luo %q %q %lud\n", name, rd.mode, rd.uid, rd.gid, rd.mtime);
+					goto DoCreateDb;
+				}
 				if(dbd.mtime==ld.mtime && dbd.length==ld.length)
 					goto DoCreate;
 				if(resolve1=='s')
@@ -449,6 +463,10 @@ main(int argc, char **argv)
 					goto DoCopy;
 				else if(resolve1=='c')
 					goto DoCopyDb;
+				if(samecontents(local, remote) > 0){
+					chat("= %q %luo %q %q %lud\n", name, rd.mode, rd.uid, rd.gid, rd.mtime);
+					goto DoCopyDb;
+				}
 				if(havelocal)
 					conflict(name, "locally created; will not update");
 				else
@@ -486,11 +504,15 @@ main(int argc, char **argv)
 					/* no skip=1 */
 					break;
 				}
+				if(samecontents(local, remote) > 0){
+					chat("= %q %luo %q %q %lud\n", name, rd.mode, rd.uid, rd.gid, rd.mtime);
+					goto DoCopyDb;
+				}
 				if(resolve1 == 's')
 					goto DoCopy;
 				else if(resolve1 == 'c')
 					break;
-				conflict(name, "locally modified; will not update");
+				conflict(name, "locally modified; will not update [%llud %lud -> %llud %lud]", dbd.length, dbd.mtime, ld.length, ld.mtime);
 				skip = 1;
 				continue;
 			}
@@ -596,7 +618,7 @@ main(int argc, char **argv)
 					continue;
 				}
 				SET(checkedmatch4);
-				if(resolve1 == 's')
+				if(resolve1 == 's' || samecontents(local, remote) > 0)
 					goto DoMeta;
 				else if(resolve1 == 'c')
 					break;
@@ -732,13 +754,10 @@ conflict(char *name, char *f, ...)
 	s = vsmprint(f, arg);
 	va_end(arg);
 
-	fprint(2, "%s: %s\n", name, s);
+	fprint(2, "! %s: %s\n", name, s);
 	free(s);
 
 	nconf++;
-//	if(nconf%16 == 0)
-//		conf = erealloc(conf, (nconf+16)*sizeof(conf[0]));
-//	conf[nconf++] = estrdup(name);
 }
 
 void
@@ -786,6 +805,27 @@ localdirstat(char *name, Dir *d)
 
 enum { DEFB = 8192 };
 
+static int
+cmp1(int fd1, int fd2)
+{
+	char buf1[DEFB];
+	char buf2[DEFB];
+	int n1, n2;
+	
+	for(;;){
+		n1 = readn(fd1, buf1, DEFB);
+		n2 = readn(fd2, buf2, DEFB);
+		if(n1 < 0 || n2 < 0)
+			return -1;
+		if(n1 != n2)
+			return 0;
+		if(n1 == 0)
+			return 1;
+		if(memcmp(buf1, buf2, n1) != 0)
+			return 0;
+	}
+}
+
 static int
 copy1(int fdf, int fdt, char *from, char *to)
 {
@@ -1059,6 +1099,80 @@ okay:
 	return 0;
 }
 
+int
+samecontents(char *local, char *remote)
+{
+	Dir *d0, *d1;
+	int rfd, tfd, lfd, ret;
+	char tmp[32];
+
+	/* quick check: sizes must match */
+	d1 = nil;
+	if((d0 = dirstat(local)) == nil || (d1 = dirstat(remote)) == nil){
+		free(d0);
+		free(d1);
+		return -1;
+	}
+	if(d0->length != d1->length){
+		free(d0);
+		free(d1);
+		return 0;
+	}
+
+Again:
+	if((rfd = open(remote, OREAD)) < 0)
+		return -1;
+	d0 = dirfstat(rfd);
+	if(d0 == nil){
+		close(rfd);
+		return -1;
+	}
+
+	strcpy(tmp, "/tmp/replicaXXXXXXXX");
+	tfd = opentemp(tmp);
+	if(tfd < 0){
+		close(rfd);
+		free(d0);
+		return -1;
+	}
+	if(copy1(rfd, tfd, remote, tmp) < 0 || (d1 = dirfstat(rfd)) == nil){
+		close(rfd);
+		close(tfd);
+		free(d0);
+		return -1;
+	}
+	close(rfd);
+	if(d0->qid.path != d1->qid.path
+	|| d0->qid.vers != d1->qid.vers
+	|| d0->mtime != d1->mtime
+	|| d0->length != d1->length){
+		/* file changed underfoot; go around again */
+		close(tfd);
+		free(d0);
+		free(d1);
+		goto Again;
+	}
+	free(d1);
+	free(d0);
+	if(seek(tfd, 0, 0) != 0){
+		close(tfd);
+		return -1;
+	}
+
+	/*
+	 * now compare
+	 */
+	if((lfd = open(local, OREAD)) < 0){
+		close(tfd);
+		return -1;
+	}
+	
+	ret = cmp1(lfd, tfd);
+	close(lfd);
+	close(tfd);
+	return ret;
+}
+
 /*
  * Applylog might try to overwrite itself.
  * To avoid problems with this, we copy ourselves

+ 1 - 1
sys/src/cmd/rio/wind.c

@@ -710,7 +710,7 @@ wrepaint(Window *w)
 {
 	wsetcols(w);
 	if(!w->mouseopen)
-		_frredraw(w, w->Frame.r.min, w->cols[TEXT], nil);
+		frredraw(w);
 	if(w == input){
 		wborder(w, Selborder);
 		wsetcursor(w, 0);

+ 266 - 0
sys/src/games/mp3dec/audio.c

@@ -0,0 +1,266 @@
+
+#include "mpg123.h"
+
+void audio_info_struct_init(struct audio_info_struct *ai)
+{
+#ifdef AUDIO_USES_FD
+  ai->fn = -1;
+#endif
+#ifdef SGI
+#if 0
+  ALconfig config;
+  ALport port;
+#endif
+#endif
+  ai->rate = -1;
+  ai->gain = -1;
+  ai->output = -1;
+#ifdef ALSA
+  ai->handle = NULL;
+  ai->alsa_format.format = -1;
+  ai->alsa_format.rate = -1;
+  ai->alsa_format.channels = -1;
+#endif
+  ai->device = NULL;
+  ai->channels = -1;
+  ai->format = -1;
+}
+
+#define NUM_CHANNELS 2
+#define NUM_ENCODINGS 6
+#define NUM_RATES 10
+
+struct audio_name audio_val2name[NUM_ENCODINGS+1] = {
+ { AUDIO_FORMAT_SIGNED_16  , "signed 16 bit" , "s16 " } ,
+ { AUDIO_FORMAT_UNSIGNED_16, "unsigned 16 bit" , "u16 " } ,  
+ { AUDIO_FORMAT_UNSIGNED_8 , "unsigned 8 bit" , "u8  " } ,
+ { AUDIO_FORMAT_SIGNED_8   , "signed 8 bit" , "s8  " } ,
+ { AUDIO_FORMAT_ULAW_8     , "mu-law (8 bit)" , "ulaw " } ,
+ { AUDIO_FORMAT_ALAW_8     , "a-law (8 bit)" , "alaw " } ,
+ { -1 , NULL }
+};
+
+#if 0
+static char *channel_name[NUM_CHANNELS] = 
+ { "mono" , "stereo" };
+#endif
+
+static int channels[NUM_CHANNELS] = { 1 , 2 };
+static int rates[NUM_RATES] = { 
+	 8000, 11025, 12000, 
+	16000, 22050, 24000,
+	32000, 44100, 48000,
+	8000	/* 8000 = dummy for user forced */
+
+};
+static int encodings[NUM_ENCODINGS] = {
+ AUDIO_FORMAT_SIGNED_16, 
+ AUDIO_FORMAT_UNSIGNED_16,
+ AUDIO_FORMAT_UNSIGNED_8,
+ AUDIO_FORMAT_SIGNED_8,
+ AUDIO_FORMAT_ULAW_8,
+ AUDIO_FORMAT_ALAW_8
+};
+
+static char capabilities[NUM_CHANNELS][NUM_ENCODINGS][NUM_RATES];
+
+void audio_capabilities(struct audio_info_struct *ai)
+{
+	int fmts;
+	int i,j,k,k1=NUM_RATES-1;
+	struct audio_info_struct ai1 = *ai;
+
+        if (param.outmode != DECODE_AUDIO) {
+		memset(capabilities,1,sizeof(capabilities));
+		return;
+	}
+
+	memset(capabilities,0,sizeof(capabilities));
+	if(param.force_rate) {
+		rates[NUM_RATES-1] = param.force_rate;
+		k1 = NUM_RATES;
+	}
+
+	if(audio_open(&ai1) < 0) {
+		perror("audio");
+		exit(1);
+	}
+
+	for(i=0;i<NUM_CHANNELS;i++) {
+		for(j=0;j<NUM_RATES;j++) {
+			ai1.channels = channels[i];
+			ai1.rate = rates[j];
+			fmts = audio_get_formats(&ai1);
+			if(fmts < 0)
+				continue;
+			for(k=0;k<NUM_ENCODINGS;k++) {
+				if((fmts & encodings[k]) == encodings[k])
+					capabilities[i][k][j] = 1;
+			}
+		}
+	}
+
+	audio_close(&ai1);
+
+	if(param.verbose > 1) {
+		fprintf(stderr,"\nAudio capabilities:\n        |");
+		for(j=0;j<NUM_ENCODINGS;j++) {
+			fprintf(stderr," %5s |",audio_val2name[j].sname);
+		}
+		fprintf(stderr,"\n --------------------------------------------------------\n");
+		for(k=0;k<k1;k++) {
+			fprintf(stderr," %5d  |",rates[k]);
+			for(j=0;j<NUM_ENCODINGS;j++) {
+				if(capabilities[0][j][k]) {
+					if(capabilities[1][j][k])
+						fprintf(stderr,"  M/S  |");
+					else
+						fprintf(stderr,"   M   |");
+				}
+				else if(capabilities[1][j][k])
+					fprintf(stderr,"   S   |");
+				else
+					fprintf(stderr,"       |");
+			}
+			fprintf(stderr,"\n");
+		}
+		fprintf(stderr,"\n");
+	}
+}
+
+static int rate2num(int r)
+{
+	int i;
+	for(i=0;i<NUM_RATES;i++) 
+		if(rates[i] == r)
+			return i;
+	return -1;
+}
+
+
+static int audio_fit_cap_helper(struct audio_info_struct *ai,int rn,int f0,int f2,int c)
+{
+	int i;
+
+        if(rn >= 0) {
+                for(i=f0;i<f2;i++) {
+                        if(capabilities[c][i][rn]) {
+                                ai->rate = rates[rn];
+                                ai->format = encodings[i];
+                                ai->channels = channels[c];
+				return 1;
+                        }
+                }
+        }
+	return 0;
+
+}
+
+/*
+ * c=num of channels of stream
+ * r=rate of stream
+ */
+void audio_fit_capabilities(struct audio_info_struct *ai,int c,int r)
+{
+	int rn;
+	int f0=0;
+	
+	if(param.force_8bit) {
+		f0 = 2;
+	}
+
+	c--; /* stereo=1 ,mono=0 */
+
+	if(param.force_mono >= 0)
+		c = 0;
+	if(param.force_stereo)
+		c = 1;
+
+	if(param.force_rate) {
+		rn = rate2num(param.force_rate);
+		if(audio_fit_cap_helper(ai,rn,f0,2,c))
+			return;
+		if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
+			return;
+
+		if(c == 1 && !param.force_stereo)
+			c = 0;
+		else if(c == 0 && !param.force_mono)
+			c = 1;
+
+		if(audio_fit_cap_helper(ai,rn,f0,2,c))
+			return;
+		if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
+			return;
+
+		fprintf(stderr,"No supported rate found!\n");
+		exit(1);
+	}
+
+	rn = rate2num(r>>0);
+	if(audio_fit_cap_helper(ai,rn,f0,2,c))
+		return;
+	rn = rate2num(r>>1);
+	if(audio_fit_cap_helper(ai,rn,f0,2,c))
+		return;
+	rn = rate2num(r>>2);
+	if(audio_fit_cap_helper(ai,rn,f0,2,c))
+		return;
+
+	rn = rate2num(r>>0);
+	if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
+		return;
+	rn = rate2num(r>>1);
+	if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
+		return;
+	rn = rate2num(r>>2);
+	if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
+		return;
+
+
+        if(c == 1 && !param.force_stereo)
+		c = 0;
+        else if(c == 0 && !param.force_mono)
+                c = 1;
+
+        rn = rate2num(r>>0);
+        if(audio_fit_cap_helper(ai,rn,f0,2,c))
+                return;
+        rn = rate2num(r>>1);
+        if(audio_fit_cap_helper(ai,rn,f0,2,c))
+                return;
+        rn = rate2num(r>>2);
+        if(audio_fit_cap_helper(ai,rn,f0,2,c))
+                return;
+
+        rn = rate2num(r>>0);
+        if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
+                return;
+        rn = rate2num(r>>1);
+        if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
+                return;
+        rn = rate2num(r>>2);
+        if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
+                return;
+
+	fprintf(stderr,"No supported rate found!\n");
+	exit(1);
+}
+
+char *audio_encoding_name(int format)
+{
+	int i;
+
+	for(i=0;i<NUM_ENCODINGS;i++) {
+		if(audio_val2name[i].val == format)
+			return audio_val2name[i].name;
+	}
+	return "Unknown";
+}
+
+#if !defined(SOLARIS) && !defined(__NetBSD__) || defined(NAS)
+void audio_queueflush(struct audio_info_struct *ai)
+{
+}
+#endif
+

+ 89 - 0
sys/src/games/mp3dec/audio.h

@@ -0,0 +1,89 @@
+/* 
+ * Audio 'LIB' defines
+ */
+
+#define AUDIO_OUT_HEADPHONES       0x01
+#define AUDIO_OUT_INTERNAL_SPEAKER 0x02
+#define AUDIO_OUT_LINE_OUT         0x04
+
+enum { DECODE_TEST, DECODE_AUDIO, DECODE_FILE, DECODE_BUFFER, DECODE_WAV,
+	DECODE_AU,DECODE_CDR,DECODE_AUDIOFILE };
+
+#define AUDIO_FORMAT_MASK	  0x100
+#define AUDIO_FORMAT_16		  0x100
+#define AUDIO_FORMAT_8		  0x000
+
+#define AUDIO_FORMAT_SIGNED_16    0x110
+#define AUDIO_FORMAT_UNSIGNED_16  0x120
+#define AUDIO_FORMAT_UNSIGNED_8   0x1
+#define AUDIO_FORMAT_SIGNED_8     0x2
+#define AUDIO_FORMAT_ULAW_8       0x4
+#define AUDIO_FORMAT_ALAW_8       0x8
+
+/* 3% rate tolerance */
+#define AUDIO_RATE_TOLERANCE	  3
+
+#if 0
+#if defined(HPUX) || defined(SUNOS) || defined(SOLARIS) || defined(OSS) || defined(__NetBSD__) || defined(SPARCLINUX) || defined(__FreeBSD__)
+#endif
+#endif
+
+#define AUDIO_USES_FD
+
+#ifdef SGI
+/* #include <audio.h> */
+#include <dmedia/audio.h>
+#endif
+
+
+#ifdef ALSA
+#include <sys/asoundlib.h>
+#endif
+
+struct audio_info_struct
+{
+#ifdef AUDIO_USES_FD
+  int fn; /* filenumber */
+#endif
+#ifdef SGI
+  ALconfig config;
+  ALport port;
+#endif
+  long rate;
+  long gain;
+  int output;
+#ifdef ALSA
+  void *handle;
+  snd_pcm_format_t alsa_format;
+#endif
+  char *device;
+  int channels;
+  int format;
+  int private1;
+  void *private2;
+};
+
+struct audio_name {
+  int  val;
+  char *name;
+  char *sname;
+};
+
+extern void audio_capabilities(struct audio_info_struct *);
+extern void audio_fit_capabilities(struct audio_info_struct *ai,int c,int r);
+
+extern char *audio_encoding_name(int format);
+
+extern int audio_play_samples(struct audio_info_struct *,unsigned char *,int);
+extern int audio_open(struct audio_info_struct *);
+extern int audio_reset_parameters(struct audio_info_struct *);
+extern int audio_rate_best_match(struct audio_info_struct *ai);
+extern int audio_set_rate(struct audio_info_struct *);
+extern int audio_set_format(struct audio_info_struct *);
+extern int audio_get_formats(struct audio_info_struct *);
+extern int audio_set_channels(struct audio_info_struct *);
+extern int audio_write_sample(struct audio_info_struct *,short *,int);
+extern int audio_close(struct audio_info_struct *);
+extern void audio_info_struct_init(struct audio_info_struct *);
+extern void audio_queueflush(struct audio_info_struct *ai);
+

+ 48 - 0
sys/src/games/mp3dec/audio_dummy.c

@@ -0,0 +1,48 @@
+
+#include "mpg123.h"
+
+int audio_open(struct audio_info_struct *ai)
+{
+  fprintf(stderr,"No audio device support compiled into this binary (use -s).\n");
+  return -1;
+}
+
+int audio_reset_parameters(struct audio_info_struct *ai)
+{
+  return 0;
+}
+
+int audio_rate_best_match(struct audio_info_struct *ai)
+{
+  return 0;
+}
+
+int audio_set_rate(struct audio_info_struct *ai)
+{
+  return 0;
+}
+
+int audio_set_channels(struct audio_info_struct *ai)
+{
+  return 0;
+}
+
+int audio_set_format(struct audio_info_struct *ai)
+{
+  return 0;
+}
+
+int audio_get_formats(struct audio_info_struct *ai)
+{
+  return AUDIO_FORMAT_SIGNED_16;
+}
+
+int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
+{
+  return len;
+}
+
+int audio_close(struct audio_info_struct *ai)
+{
+  return 0;
+}

+ 231 - 0
sys/src/games/mp3dec/buffer.c

@@ -0,0 +1,231 @@
+/*
+ *   buffer.c
+ *
+ *   Oliver Fromme  <oliver.fromme@heim3.tu-clausthal.de>
+ *   Mon Apr 14 03:53:18 MET DST 1997
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+
+#include "mpg123.h"
+
+int outburst = MAXOUTBURST;
+int preload;
+
+static int intflag = FALSE;
+static int usr1flag = FALSE;
+
+static void catch_interrupt (void)
+{
+	intflag = TRUE;
+}
+
+static void catch_usr1 (void)
+{
+	usr1flag = TRUE;
+}
+
+/* Interfaces to writer process */
+
+extern void buffer_sig(int signal, int block);
+
+void buffer_ignore_lowmem(void)
+{
+#ifndef NOXFERMEM
+	if(buffermem->wakeme[XF_READER])
+		xfermem_putcmd(buffermem->fd[XF_WRITER], XF_CMD_WAKEUP);
+#endif
+}
+
+void buffer_end(void)
+{
+#ifndef NOXFERMEM
+	xfermem_putcmd(buffermem->fd[XF_WRITER], XF_CMD_TERMINATE);
+#endif
+}
+
+void buffer_resync(void)
+{
+	buffer_sig(SIGINT, TRUE);
+}
+
+void buffer_reset(void)
+{
+	buffer_sig(SIGUSR1, TRUE);
+}
+
+void buffer_start(void)
+{
+	buffer_sig(SIGCONT, FALSE);
+}
+
+void buffer_stop(void)
+{
+	buffer_sig(SIGSTOP, FALSE);
+}
+
+extern int buffer_pid;
+
+void buffer_sig(int signal, int block)
+{
+	
+#ifndef NOXFERMEM
+	
+	kill(buffer_pid, signal);
+	
+	if (!buffermem || !block)
+		return;
+
+	if(xfermem_block(XF_WRITER, buffermem) != XF_CMD_WAKEUP) 
+		perror("Could not resync/reset buffers");
+#endif
+	
+	return;
+}
+
+#ifndef NOXFERMEM
+
+void buffer_loop(struct audio_info_struct *ai, sigset_t *oldsigset)
+{
+	int bytes;
+	int my_fd = buffermem->fd[XF_READER];
+	txfermem *xf = buffermem;
+	int done = FALSE;
+
+	catchsignal (SIGINT, catch_interrupt);
+	catchsignal (SIGUSR1, catch_usr1);
+	sigprocmask (SIG_SETMASK, oldsigset, NULL);
+	if (param.outmode == DECODE_AUDIO) {
+		if (audio_open(ai) < 0) {
+			perror("audio");
+			exit(1);
+		}
+	}
+
+	for (;;) {
+		if (intflag) {
+			intflag = FALSE;
+			if (param.outmode == DECODE_AUDIO)
+				audio_queueflush (ai);
+			xf->readindex = xf->freeindex;
+			if (xf->wakeme[XF_WRITER])
+				xfermem_putcmd(my_fd, XF_CMD_WAKEUP);
+		}
+		if (usr1flag) {
+			usr1flag = FALSE;
+			/*   close and re-open in order to flush
+			 *   the device's internal buffer before
+			 *   changing the sample rate.   [OF]
+			 */
+			/* writer must block when sending SIGUSR1
+			 * or we will lose all data processed 
+			 * in the meantime! [dk]
+			 */
+			xf->readindex = xf->freeindex;
+			/* We've nailed down the new starting location -
+			 * writer is now safe to go on. [dk]
+			 */
+			if (xf->wakeme[XF_WRITER])
+				xfermem_putcmd(my_fd, XF_CMD_WAKEUP);
+			if (param.outmode == DECODE_AUDIO) {
+				audio_close (ai);
+				ai->rate = xf->buf[0]; 
+				ai->channels = xf->buf[1]; 
+				ai->format = xf->buf[2];
+				if (audio_open(ai) < 0) {
+					perror("audio");
+					exit(1);
+				}
+			}
+		}
+		if ( (bytes = xfermem_get_usedspace(xf)) < outburst ) {
+			/* if we got a buffer underrun we first
+			 * fill 1/8 of the buffer before continue/start
+			 * playing */
+			preload = xf->size>>3;
+			if(preload < outburst)
+				preload = outburst;
+		}
+		if(bytes < preload) {
+			int cmd;
+			if (done && !bytes) { 
+				break;
+			}
+
+			if(!done) {
+
+				cmd = xfermem_block(XF_READER, xf);
+
+				switch(cmd) {
+
+					/* More input pending. */
+					case XF_CMD_WAKEUP_INFO:
+						continue;
+					/* Yes, we know buffer is low but
+					 * know we don't care.
+					 */
+					case XF_CMD_WAKEUP:
+						break;	/* Proceed playing. */
+					case XF_CMD_TERMINATE:
+						/* Proceed playing without 
+						 * blocking any further.
+						 */
+						done=TRUE;
+						break;
+					case -1:
+						if(errno==EINTR)
+							continue;
+						perror("Yuck! Error in buffer handling...");
+						done = TRUE;
+						xf->readindex = xf->freeindex;
+						xfermem_putcmd(xf->fd[XF_READER], XF_CMD_TERMINATE);
+						break;
+					default:
+						fprintf(stderr, "\nEh!? Received unknown command 0x%x in buffer process. Tell Daniel!\n", cmd);
+				}
+			}
+		}
+		preload = outburst; /* set preload to lower mark */
+		if (bytes > xf->size - xf->readindex)
+			bytes = xf->size - xf->readindex;
+		if (bytes > outburst)
+			bytes = outburst;
+
+		if (param.outmode == DECODE_FILE)
+			bytes = write(OutputDescriptor, xf->data + xf->readindex, bytes);
+		else if (param.outmode == DECODE_AUDIO)
+			bytes = audio_play_samples(ai,
+				(unsigned char *) (xf->data + xf->readindex), bytes);
+
+		if(bytes < 0) {
+			bytes = 0;
+			if(errno != EINTR) {
+				perror("Ouch ... error while writing audio data: ");
+				/*
+				 * done==TRUE tells writer process to stop
+				 * sending data. There might be some latency
+				 * involved when resetting readindex to 
+				 * freeindex so we might need more than one
+				 * cycle to terminate. (The number of cycles
+				 * should be finite unless I managed to mess
+				 * up something. ;-) [dk]
+				 */
+				done = TRUE;	
+				xf->readindex = xf->freeindex;
+				xfermem_putcmd(xf->fd[XF_READER], XF_CMD_TERMINATE);
+			}
+		}
+
+		xf->readindex = (xf->readindex + bytes) % xf->size;
+		if (xf->wakeme[XF_WRITER])
+			xfermem_putcmd(my_fd, XF_CMD_WAKEUP);
+	}
+
+	if (param.outmode == DECODE_AUDIO)
+		audio_close (ai);
+}
+
+#endif
+
+/* EOF */

+ 13 - 0
sys/src/games/mp3dec/buffer.h

@@ -0,0 +1,13 @@
+/*
+ * Application specific interaction between main and buffer
+ * process. This is much less generic than the functions in
+ * xfermem so I chose to put it in buffer.[hc].
+ * 01/28/99 [dk]
+ */
+
+void buffer_ignore_lowmem(void);
+void buffer_end(void);
+void buffer_resync(void);
+void buffer_reset(void);
+void buffer_start(void);
+void buffer_stop(void);

+ 732 - 0
sys/src/games/mp3dec/common.c

@@ -0,0 +1,732 @@
+#include <ctype.h>
+#include <stdlib.h>
+#include <signal.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+
+#include <fcntl.h>
+
+#ifdef READ_MMAP
+#include <sys/mman.h>
+#ifndef MAP_FAILED
+#define MAP_FAILED ( (void *) -1 )
+#endif
+#endif
+
+#include "mpg123.h"
+#include "genre.h"
+#include "common.h"
+
+int tabsel_123[2][3][16] = {
+   { {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,},
+     {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,},
+     {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,} },
+
+   { {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,},
+     {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,},
+     {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} }
+};
+
+long freqs[9] = { 44100, 48000, 32000, 22050, 24000, 16000 , 11025 , 12000 , 8000 };
+
+struct bitstream_info bsi;
+
+static int fsizeold=0,ssize;
+static unsigned char bsspace[2][MAXFRAMESIZE+512]; /* MAXFRAMESIZE */
+static unsigned char *bsbuf=bsspace[1],*bsbufold;
+static int bsnum=0;
+
+static unsigned long oldhead = 0;
+unsigned long firsthead=0;
+
+unsigned char *pcm_sample;
+int pcm_point = 0;
+int audiobufsize = AUDIOBUFSIZE;
+
+#ifdef VARMODESUPPORT
+	/*
+	 *   This is a dirty hack!  It might burn your PC and kill your cat!
+	 *   When in "varmode", specially formatted layer-3 mpeg files are
+	 *   expected as input -- it will NOT work with standard mpeg files.
+	 *   The reason for this:
+	 *   Varmode mpeg files enable my own GUI player to perform fast
+	 *   forward and backward functions, and to jump to an arbitrary
+	 *   timestamp position within the file.  This would be possible
+	 *   with standard mpeg files, too, but it would be a lot harder to
+	 *   implement.
+	 *   A filter for converting standard mpeg to varmode mpeg is
+	 *   available on request, but it's really not useful on its own.
+	 *
+	 *   Oliver Fromme  <oliver.fromme@heim3.tu-clausthal.de>
+	 *   Mon Mar 24 00:04:24 MET 1997
+	 */
+int varmode = FALSE;
+int playlimit;
+#endif
+
+static int decode_header(struct frame *fr,unsigned long newhead);
+
+void audio_flush(int outmode, struct audio_info_struct *ai)
+{
+  if (pcm_point) {
+    switch (outmode) {
+      case DECODE_FILE:
+        write (OutputDescriptor, pcm_sample, pcm_point);
+        break;
+      case DECODE_AUDIO:
+        audio_play_samples (ai, pcm_sample, pcm_point);
+        break;
+      case DECODE_BUFFER:
+        write (buffer_fd[1], pcm_sample, pcm_point);
+        break;
+      case DECODE_WAV:
+      case DECODE_CDR:
+      case DECODE_AU:
+        wav_write(pcm_sample, pcm_point);
+        break;
+    }
+    pcm_point = 0;
+  }
+}
+
+#if !defined(WIN32) && !defined(GENERIC)
+void (*catchsignal(int signum, void(*handler)()))()
+{
+  struct sigaction new_sa;
+  struct sigaction old_sa;
+
+#ifdef DONT_CATCH_SIGNALS
+  printf ("Not catching any signals.\n");
+  return ((void (*)()) -1);
+#endif
+
+  new_sa.sa_handler = handler;
+  sigemptyset(&new_sa.sa_mask);
+  new_sa.sa_flags = 0;
+  if (sigaction(signum, &new_sa, &old_sa) == -1)
+    return ((void (*)()) -1);
+  return (old_sa.sa_handler);
+}
+#endif
+
+void read_frame_init (void)
+{
+    oldhead = 0;
+    firsthead = 0;
+}
+
+int head_check(unsigned long head)
+{
+    if( (head & 0xffe00000) != 0xffe00000)
+	return FALSE;
+    if(!((head>>17)&3))
+	return FALSE;
+    if( ((head>>12)&0xf) == 0xf)
+	return FALSE;
+    if( ((head>>10)&0x3) == 0x3 )
+	return FALSE;
+    if ((head & 0xffff0000) == 0xfffe0000)
+      return FALSE;
+
+    return TRUE;
+}
+
+
+
+/*****************************************************************
+ * read next frame
+ */
+int read_frame(struct frame *fr)
+{
+  unsigned long newhead;
+  static unsigned char ssave[34];
+
+  fsizeold=fr->framesize;       /* for Layer3 */
+
+  if (param.halfspeed) {
+    static int halfphase = 0;
+    if (halfphase--) {
+      bsi.bitindex = 0;
+      bsi.wordpointer = (unsigned char *) bsbuf;
+      if (fr->lay == 3)
+        memcpy (bsbuf, ssave, ssize);
+      return 1;
+    }
+    else
+      halfphase = param.halfspeed - 1;
+  }
+
+read_again:
+  if(!rd->head_read(rd,&newhead))
+    return FALSE;
+
+  if(1 || oldhead != newhead || !oldhead)
+  {
+
+init_resync:
+
+    fr->header_change = 2;
+    if(oldhead) {
+      if((oldhead & 0xc00) == (newhead & 0xc00)) {
+        if( (oldhead & 0xc0) == 0 && (newhead & 0xc0) == 0)
+    	  fr->header_change = 1; 
+        else if( (oldhead & 0xc0) > 0 && (newhead & 0xc0) > 0)
+	  fr->header_change = 1;
+      }
+    }
+
+
+#ifdef SKIP_JUNK
+	if(!firsthead && !head_check(newhead) ) {
+		int i;
+
+		fprintf(stderr,"Junk at the beginning %08lx\n",newhead);
+
+		/* I even saw RIFF headers at the beginning of MPEG streams ;( */
+		if(newhead == ('R'<<24)+('I'<<16)+('F'<<8)+'F') {
+			if(!rd->head_read(rd,&newhead))
+				return 0;
+			while(newhead != ('d'<<24)+('a'<<16)+('t'<<8)+'a') {
+				if(!rd->head_shift(rd,&newhead))
+					return 0;
+			}
+			if(!rd->head_read(rd,&newhead))
+				return 0;
+			fprintf(stderr,"Skipped RIFF header!\n");
+			goto read_again;
+		}
+		{
+			/* step in byte steps through next 64K */
+			for(i=0;i<65536;i++) {
+				if(!rd->head_shift(rd,&newhead))
+					return 0;
+				if(head_check(newhead))
+					break;
+#if 0
+fprintf(stderr,"%08lx ",newhead);
+#endif
+			}
+			if(i == 65536) {
+				fprintf(stderr,"Giving up searching valid MPEG header\n");
+				return 0;
+			}
+		}
+		/* 
+		 * should we additionaly check, whether a new frame starts at
+		 * the next expected position? (some kind of read ahead)
+		 * We could implement this easily, at least for files.
+		 */
+	}
+#endif
+
+    if( (newhead & 0xffe00000) != 0xffe00000) {
+      if (!param.quiet)
+        fprintf(stderr,"Illegal Audio-MPEG-Header 0x%08lx at offset 0x%lx.\n",
+              newhead,rd->tell(rd)-4);
+    /* and those ugly ID3 tags */
+      if((newhead & 0xffffff00) == ('T'<<24)+('A'<<16)+('G'<<8)) {
+           rd->skip_bytes(rd,124);
+           fprintf(stderr,"Skipped ID3 Tag!\n");
+           goto read_again;
+      }
+      if (param.tryresync) {
+        int try = 0;
+            /* Read more bytes until we find something that looks
+               reasonably like a valid header.  This is not a
+               perfect strategy, but it should get us back on the
+               track within a short time (and hopefully without
+               too much distortion in the audio output).  */
+        do {
+          try++;
+          if(!rd->head_shift(rd,&newhead))
+		return 0;
+          if (!oldhead)
+            goto init_resync;       /* "considered harmful", eh? */
+
+        } while ((newhead & HDRCMPMASK) != (oldhead & HDRCMPMASK)
+              && (newhead & HDRCMPMASK) != (firsthead & HDRCMPMASK));
+        if (!param.quiet)
+          fprintf (stderr, "Skipped %d bytes in input.\n", try);
+      }
+      else
+        return (0);
+    }
+
+    if (!firsthead) {
+      if(!decode_header(fr,newhead))
+        goto read_again;
+      firsthead = newhead;
+    }
+    else
+      if(!decode_header(fr,newhead))
+        return 0;
+
+  }
+  else
+    fr->header_change = 0;
+
+  /* flip/init buffer for Layer 3 */
+  bsbufold = bsbuf;
+  bsbuf = bsspace[bsnum]+512;
+  bsnum = (bsnum + 1) & 1;
+
+  /* read main data into memory */
+  if(!rd->read_frame_body(rd,bsbuf,fr->framesize))
+    return 0;
+
+  bsi.bitindex = 0;
+  bsi.wordpointer = (unsigned char *) bsbuf;
+
+  if (param.halfspeed && fr->lay == 3)
+    memcpy (ssave, bsbuf, ssize);
+
+  return 1;
+
+}
+
+/****************************************
+ * HACK,HACK,HACK: step back <num> frames
+ * can only work if the 'stream' isn't a real stream but a file
+ */
+int back_frame(struct reader *rds,struct frame *fr,int num)
+{
+  long bytes;
+  unsigned long newhead;
+  
+  if(!firsthead)
+    return 0;
+  
+  bytes = (fr->framesize+8)*(num+2);
+  
+  if(rds->back_bytes(rds,bytes) < 0)
+    return -1;
+  if(!rds->head_read(rds,&newhead))
+    return -1;
+  
+  while( (newhead & HDRCMPMASK) != (firsthead & HDRCMPMASK) ) {
+    if(!rds->head_shift(rds,&newhead))
+      return -1;
+  }
+  
+  if(rds->back_bytes(rds,4) <0)
+    return -1;
+
+  read_frame(fr);
+  read_frame(fr);
+  
+  if(fr->lay == 3) {
+    set_pointer(512);
+  }
+  
+  return 0;
+}
+
+
+/*
+ * decode a header and write the information
+ * into the frame structure
+ */
+static int decode_header(struct frame *fr,unsigned long newhead)
+{
+    if(!head_check(newhead))
+      return 0;
+
+    if( newhead & (1<<20) ) {
+      fr->lsf = (newhead & (1<<19)) ? 0x0 : 0x1;
+      fr->mpeg25 = 0;
+    }
+    else {
+      fr->lsf = 1;
+      fr->mpeg25 = 1;
+    }
+    
+    if (!param.tryresync || !oldhead) {
+          /* If "tryresync" is true, assume that certain
+             parameters do not change within the stream! */
+      fr->lay = 4-((newhead>>17)&3);
+      if( ((newhead>>10)&0x3) == 0x3) {
+        fprintf(stderr,"Stream error\n");
+        exit(1);
+      }
+      if(fr->mpeg25) {
+        fr->sampling_frequency = 6 + ((newhead>>10)&0x3);
+      }
+      else
+        fr->sampling_frequency = ((newhead>>10)&0x3) + (fr->lsf*3);
+      fr->error_protection = ((newhead>>16)&0x1)^0x1;
+    }
+
+    fr->bitrate_index = ((newhead>>12)&0xf);
+    fr->padding   = ((newhead>>9)&0x1);
+    fr->extension = ((newhead>>8)&0x1);
+    fr->mode      = ((newhead>>6)&0x3);
+    fr->mode_ext  = ((newhead>>4)&0x3);
+    fr->copyright = ((newhead>>3)&0x1);
+    fr->original  = ((newhead>>2)&0x1);
+    fr->emphasis  = newhead & 0x3;
+
+    fr->stereo    = (fr->mode == MPG_MD_MONO) ? 1 : 2;
+
+    oldhead = newhead;
+
+    if(!fr->bitrate_index) {
+      fprintf(stderr,"Free format not supported: (head %08lx)\n",newhead);
+      return (0);
+    }
+
+    switch(fr->lay) {
+      case 1:
+	fr->do_layer = do_layer1;
+#ifdef VARMODESUPPORT
+        if (varmode) {
+          fprintf(stderr,"Sorry, layer-1 not supported in varmode.\n"); 
+          return (0);
+        }
+#endif
+        fr->framesize  = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000;
+        fr->framesize /= freqs[fr->sampling_frequency];
+        fr->framesize  = ((fr->framesize+fr->padding)<<2)-4;
+        break;
+      case 2:
+	fr->do_layer = do_layer2;
+#ifdef VARMODESUPPORT
+        if (varmode) {
+          fprintf(stderr,"Sorry, layer-2 not supported in varmode.\n"); 
+          return (0);
+        }
+#endif
+        fr->framesize = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000;
+        fr->framesize /= freqs[fr->sampling_frequency];
+        fr->framesize += fr->padding - 4;
+        break;
+      case 3:
+        fr->do_layer = do_layer3;
+        if(fr->lsf)
+          ssize = (fr->stereo == 1) ? 9 : 17;
+        else
+          ssize = (fr->stereo == 1) ? 17 : 32;
+        if(fr->error_protection)
+          ssize += 2;
+        fr->framesize  = (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000;
+        fr->framesize /= freqs[fr->sampling_frequency]<<(fr->lsf);
+        fr->framesize = fr->framesize + fr->padding - 4;
+        break; 
+      default:
+        fprintf(stderr,"Sorry, unknown layer type.\n"); 
+        return (0);
+    }
+    return 1;
+}
+
+#ifdef MPG123_REMOTE
+void print_rheader(struct frame *fr)
+{
+	static char *modes[4] = { "Stereo", "Joint-Stereo", "Dual-Channel", "Single-Channel" };
+	static char *layers[4] = { "Unknown" , "I", "II", "III" };
+	static char *mpeg_type[2] = { "1.0" , "2.0" };
+
+	/* version, layer, freq, mode, channels, bitrate, BPF */
+	fprintf(stderr,"@I %s %s %ld %s %d %d %d\n",
+			mpeg_type[fr->lsf],layers[fr->lay],freqs[fr->sampling_frequency],
+			modes[fr->mode],fr->stereo,
+			tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index],
+			fr->framesize+4);
+}
+#endif
+
+void print_header(struct frame *fr)
+{
+	static char *modes[4] = { "Stereo", "Joint-Stereo", "Dual-Channel", "Single-Channel" };
+	static char *layers[4] = { "Unknown" , "I", "II", "III" };
+
+	fprintf(stderr,"MPEG %s, Layer: %s, Freq: %ld, mode: %s, modext: %d, BPF : %d\n", 
+		fr->mpeg25 ? "2.5" : (fr->lsf ? "2.0" : "1.0"),
+		layers[fr->lay],freqs[fr->sampling_frequency],
+		modes[fr->mode],fr->mode_ext,fr->framesize+4);
+	fprintf(stderr,"Channels: %d, copyright: %s, original: %s, CRC: %s, emphasis: %d.\n",
+		fr->stereo,fr->copyright?"Yes":"No",
+		fr->original?"Yes":"No",fr->error_protection?"Yes":"No",
+		fr->emphasis);
+	fprintf(stderr,"Bitrate: %d Kbits/s, Extension value: %d\n",
+		tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index],fr->extension);
+}
+
+void print_header_compact(struct frame *fr)
+{
+	static char *modes[4] = { "stereo", "joint-stereo", "dual-channel", "mono" };
+	static char *layers[4] = { "Unknown" , "I", "II", "III" };
+ 
+	fprintf(stderr,"MPEG %s layer %s, %d kbit/s, %ld Hz %s\n",
+		fr->mpeg25 ? "2.5" : (fr->lsf ? "2.0" : "1.0"),
+		layers[fr->lay],
+		tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index],
+		freqs[fr->sampling_frequency], modes[fr->mode]);
+}
+
+void print_id3_tag(unsigned char *buf)
+{
+	struct id3tag {
+		char tag[3];
+		char title[30];
+		char artist[30];
+		char album[30];
+		char year[4];
+		char comment[30];
+		unsigned char genre;
+	};
+	struct id3tag *tag = (struct id3tag *) buf;
+	char title[31]={0,};
+	char artist[31]={0,};
+	char album[31]={0,};
+	char year[5]={0,};
+	char comment[31]={0,};
+	char genre[31]={0,};
+
+	if(param.quiet)
+		return;
+
+	strncpy(title,tag->title,30);
+	strncpy(artist,tag->artist,30);
+	strncpy(album,tag->album,30);
+	strncpy(year,tag->year,4);
+	strncpy(comment,tag->comment,30);
+
+	if ( tag->genre <= sizeof(genre_table)/sizeof(*genre_table) ) {
+		strncpy(genre, genre_table[tag->genre], 30);
+	} else {
+		strncpy(genre,"Unknown",30);
+	}
+	
+	fprintf(stderr,"Title  : %-30s  Artist: %s\n",title,artist);
+	fprintf(stderr,"Album  : %-30s  Year  : %4s\n",album,year);
+	fprintf(stderr,"Comment: %-30s  Genre : %s\n",comment,genre);
+}
+
+#if 0
+/* removed the strndup for better portability */
+/*
+ *   Allocate space for a new string containing the first
+ *   "num" characters of "src".  The resulting string is
+ *   always zero-terminated.  Returns NULL if malloc fails.
+ */
+char *strndup (const char *src, int num)
+{
+	char *dst;
+
+	if (!(dst = (char *) malloc(num+1)))
+		return (NULL);
+	dst[num] = '\0';
+	return (strncpy(dst, src, num));
+}
+#endif
+
+/*
+ *   Split "path" into directory and filename components.
+ *
+ *   Return value is 0 if no directory was specified (i.e.
+ *   "path" does not contain a '/'), OR if the directory
+ *   is the same as on the previous call to this function.
+ *
+ *   Return value is 1 if a directory was specified AND it
+ *   is different from the previous one (if any).
+ */
+
+int split_dir_file (const char *path, char **dname, char **fname)
+{
+	static char *lastdir = NULL;
+	char *slashpos;
+
+	if ((slashpos = strrchr(path, '/'))) {
+		*fname = slashpos + 1;
+		*dname = strdup(path); /* , 1 + slashpos - path); */
+		if(!(*dname)) {
+			perror("memory");
+			exit(1);
+		}
+		(*dname)[1 + slashpos - path] = 0;
+		if (lastdir && !strcmp(lastdir, *dname)) {
+			/***   same as previous directory   ***/
+			free (*dname);
+			*dname = lastdir;
+			return 0;
+		}
+		else {
+			/***   different directory   ***/
+			if (lastdir)
+				free (lastdir);
+			lastdir = *dname;
+			return 1;
+		}
+	}
+	else {
+		/***   no directory specified   ***/
+		if (lastdir) {
+			free (lastdir);
+			lastdir = NULL;
+		};
+		*dname = NULL;
+		*fname = (char *)path;
+		return 0;
+	}
+}
+
+void set_pointer(long backstep)
+{
+  bsi.wordpointer = bsbuf + ssize - backstep;
+  if (backstep)
+    memcpy(bsi.wordpointer,bsbufold+fsizeold-backstep,backstep);
+  bsi.bitindex = 0; 
+}
+
+/********************************/
+
+double compute_bpf(struct frame *fr)
+{
+	double bpf;
+
+        switch(fr->lay) {
+                case 1:
+                        bpf = tabsel_123[fr->lsf][0][fr->bitrate_index];
+                        bpf *= 12000.0 * 4.0;
+                        bpf /= freqs[fr->sampling_frequency] <<(fr->lsf);
+                        break;
+                case 2:
+                case 3:
+                        bpf = tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index];                        bpf *= 144000;
+                        bpf /= freqs[fr->sampling_frequency] << (fr->lsf);
+                        break;
+                default:
+                        bpf = 1.0;
+        }
+
+	return bpf;
+}
+
+double compute_tpf(struct frame *fr)
+{
+	static int bs[4] = { 0,384,1152,1152 };
+	double tpf;
+
+	tpf = (double) bs[fr->lay];
+	tpf /= freqs[fr->sampling_frequency] << (fr->lsf);
+	return tpf;
+}
+
+/*
+ * Returns number of frames queued up in output buffer, i.e. 
+ * offset between currently played and currently decoded frame.
+ */
+
+long compute_buffer_offset(struct frame *fr)
+{
+	long bufsize;
+	
+	/*
+	 * buffermem->buf[0] holds output sampling rate,
+	 * buffermem->buf[1] holds number of channels,
+	 * buffermem->buf[2] holds audio format of output.
+	 */
+	
+	if(!param.usebuffer || !(bufsize=xfermem_get_usedspace(buffermem))
+		|| !buffermem->buf[0] || !buffermem->buf[1])
+		return 0;
+
+	bufsize = (long)((double) bufsize / buffermem->buf[0] / 
+			buffermem->buf[1] / compute_tpf(fr));
+	
+	if((buffermem->buf[2] & AUDIO_FORMAT_MASK) == AUDIO_FORMAT_16)
+		return bufsize/2;
+	else
+		return bufsize;
+}
+
+void print_stat(struct frame *fr,int no,long buffsize,struct audio_info_struct *ai)
+{
+	double bpf,tpf,tim1,tim2;
+	double dt = 0.0;
+	int sno,rno;
+	char outbuf[256];
+
+	if(!rd || !fr) 
+		return;
+
+	outbuf[0] = 0;
+
+#ifndef GENERIC
+	{
+		struct timeval t;
+		fd_set serr;
+		int n,errfd = fileno(stderr);
+
+		t.tv_sec=t.tv_usec=0;
+
+		FD_ZERO(&serr);
+		FD_SET(errfd,&serr);
+		n = select(errfd+1,NULL,&serr,NULL,&t);
+		if(n <= 0)
+			return;
+	}
+#endif
+
+	bpf = compute_bpf(fr);
+	tpf = compute_tpf(fr);
+
+	if(buffsize > 0 && ai && ai->rate > 0 && ai->channels > 0) {
+		dt = (double) buffsize / ai->rate / ai->channels;
+		if( (ai->format & AUDIO_FORMAT_MASK) == AUDIO_FORMAT_16)
+			dt *= 0.5;
+	}
+
+        rno = 0;
+        sno = no;
+	if(rd->filelen >= 0) {
+          long t = rd->tell(rd);
+	  rno = (int)((double)(rd->filelen-t)/bpf);
+          sno = (int)((double)t/bpf);
+        }
+
+	sprintf(outbuf+strlen(outbuf),"\rFrame# %5d [%5d], ",sno,rno);
+
+	tim1 = sno*tpf-dt;
+	tim2 = rno*tpf+dt;
+#if 0
+	tim1 = tim1 < 0 ? 0.0 : tim1;
+#endif
+	tim2 = tim2 < 0 ? 0.0 : tim2;
+
+	sprintf(outbuf+strlen(outbuf),"Time: %02u:%02u.%02u [%02u:%02u.%02u], ",
+			(unsigned int)tim1/60,
+			(unsigned int)tim1%60,
+			(unsigned int)(tim1*100)%100,
+			(unsigned int)tim2/60,
+			(unsigned int)tim2%60,
+			(unsigned int)(tim2*100)%100);
+
+	if(param.usebuffer)
+		sprintf(outbuf+strlen(outbuf),"[%8ld] ",(long)buffsize);
+	write(fileno(stderr),outbuf,strlen(outbuf));
+#if 0
+	fflush(out); /* hmm not really nec. */
+#endif
+}
+
+int get_songlen(struct frame *fr,int no)
+{
+	double tpf;
+	
+	if(!fr)
+		return 0;
+	
+	if(no < 0) {
+		if(!rd || rd->filelen < 0)
+			return 0;
+		no = (double) rd->filelen / compute_bpf(fr);
+	}
+
+	tpf = compute_tpf(fr);
+	return no*tpf;
+}
+
+

+ 22 - 0
sys/src/games/mp3dec/common.h

@@ -0,0 +1,22 @@
+/*
+ * common.h
+ */
+
+/* max = 1728 */
+#define MAXFRAMESIZE 1792
+#define HDRCMPMASK 0xfffffd00
+
+extern void print_id3_tag(unsigned char *buf);
+extern unsigned long firsthead;
+extern int tabsel_123[2][3][16];
+extern double compute_tpf(struct frame *fr);
+extern double compute_bpf(struct frame *fr);
+extern long compute_buffer_offset(struct frame *fr);
+
+struct bitstream_info {
+  int bitindex;
+  unsigned char *wordpointer;
+};
+
+extern struct bitstream_info bsi;
+

+ 337 - 0
sys/src/games/mp3dec/control_generic.c

@@ -0,0 +1,337 @@
+
+/*
+ * Control interface to generic front ends.
+ * written/copyrights 1997/99 by Andreas Neuhaus (and Michael Hipp)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <sys/socket.h>
+
+#include "mpg123.h"
+
+#define MODE_STOPPED 0
+#define MODE_PLAYING 1
+#define MODE_PAUSED 2
+
+extern struct audio_info_struct ai;
+extern int buffer_pid;
+extern int tabsel_123[2][3][16];
+
+void generic_sendmsg (char *fmt, ...)
+{
+	va_list ap;
+	printf("@");
+	va_start(ap, fmt);
+	vprintf(fmt, ap);
+	va_end(ap);
+	printf("\n");
+}
+
+static double compute_bpf (struct frame *fr)
+{
+	double bpf;
+	switch(fr->lay) {
+		case 1:
+			bpf = tabsel_123[fr->lsf][0][fr->bitrate_index];
+			bpf *= 12000.0 * 4.0;
+			bpf /= freqs[fr->sampling_frequency] << (fr->lsf);
+			break;
+		case 2:
+		case 3:
+			bpf = tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index];
+			bpf *= 144000;
+			bpf /= freqs[fr->sampling_frequency] << (fr->lsf);
+			break;
+		default:
+			bpf = 1.0;
+	}
+	return bpf;
+}
+
+static double compute_tpf (struct frame *fr)
+{
+	static int bs[4] = { 0, 384, 1152, 1152 };
+	double tpf;
+
+	tpf = (double) bs[fr->lay];
+	tpf /= freqs[fr->sampling_frequency] << (fr->lsf);
+	return tpf;
+}
+
+void generic_sendstat (struct frame *fr, int no)
+{
+	long buffsize;
+	double bpf, tpf, tim1, tim2;
+	double dt = 0;
+	int sno, rno;
+
+	/* this and the 2 above functions are taken from common.c.
+	/ maybe the compute_* functions shouldn't be static there
+	/ so that they can also used here (performance problems?).
+	/ isn't there an easier way to compute the time? */
+
+	buffsize = xfermem_get_usedspace(buffermem);
+	if (!rd || !fr)
+		return;
+	bpf = compute_bpf(fr);
+	tpf = compute_tpf(fr);
+	if (buffsize > 0 && ai.rate > 0 && ai.channels > 0) {
+		dt = (double) buffsize / ai.rate / ai.channels;
+		if ((ai.format & AUDIO_FORMAT_MASK) == AUDIO_FORMAT_16)
+			dt *= .5;
+	}
+	rno = 0;
+	sno = no;
+	if (rd->filelen >= 0) {
+		long t = rd->tell(rd);
+		rno = (int)((double)(rd->filelen-t)/bpf);
+		sno = (int)((double)t/bpf);
+	}
+	tim1 = sno * tpf - dt;
+	tim2 = rno * tpf + dt;
+
+	generic_sendmsg("F %d %d %3.2f %3.2f", sno, rno, tim1, tim2);
+}
+
+extern char *genre_table[];
+extern int genre_count;
+void generic_sendinfoid3 (char *buf)
+{
+	char info[200] = "", *c;
+	int i;
+	unsigned char genre;
+	for (i=0, c=buf+3; i<124; i++, c++)
+		info[i] = *c ? *c : ' ';
+	info[i] = 0;
+	genre = *c;
+	generic_sendmsg("I ID3:%s%s", info, (genre<=genre_count) ? genre_table[genre] : "Unknown");
+}
+
+void generic_sendinfo (char *filename)
+{
+	char *s, *t;
+	s = strrchr(filename, '/');
+	if (!s)
+		s = filename;
+	else
+		s++;
+	t = strrchr(s, '.');
+	if (t)
+		*t = 0;
+	generic_sendmsg("I %s", s);
+}
+
+void control_generic (struct frame *fr)
+{
+	struct timeval tv;
+	fd_set fds;
+	int n;
+	int mode = MODE_STOPPED;
+	int init = 0;
+	int framecnt = 0;
+
+	setlinebuf(stdout);
+	printf("@R MPG123\n");
+	while (1) {
+		tv.tv_sec = 0;
+		tv.tv_usec = 0;
+		FD_ZERO(&fds);
+		FD_SET(STDIN_FILENO, &fds);
+
+		/* play frame if no command needs to be processed */
+		if (mode == MODE_PLAYING) {
+			n = select(32, &fds, NULL, NULL, &tv);
+			if (n == 0) {
+				if (!read_frame(fr)) {
+					mode = MODE_STOPPED;
+					rd->close(rd);
+					generic_sendmsg("P 0");
+					continue;
+				}
+				play_frame(init,fr);
+				if (init) {
+					static char *modes[4] = {"Stereo", "Joint-Stereo", "Dual-Channel", "Single-Channel"};
+					generic_sendmsg("S %s %d %ld %s %d %d %d %d %d %d %d %d",
+						fr->mpeg25 ? "2.5" : (fr->lsf ? "2.0" : "1.0"),
+						fr->lay,
+						freqs[fr->sampling_frequency],
+						modes[fr->mode],
+						fr->mode_ext,
+						fr->framesize+4,
+						fr->stereo,
+						fr->copyright ? 1 : 0,
+						fr->error_protection ? 1 : 0,
+						fr->emphasis,
+						tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index],
+						fr->extension);
+					init = 0;
+				}
+				framecnt++;
+				generic_sendstat(fr, framecnt);
+			}
+		}
+		else {
+			/* wait for command */
+			while (1) {
+				n = select(32, &fds, NULL, NULL, NULL);
+				if (n > 0)
+					break;
+			}
+		}
+
+		/* exit on error */
+		if (n < 0) {
+			fprintf(stderr, "Error waiting for command: %s\n", strerror(errno));
+			exit(1);
+		}
+
+		/* process command */
+		if (n > 0) {
+			int len;
+			char buf[1024];
+			char *cmd;
+
+			/* read command */
+			len = read(STDIN_FILENO, buf, sizeof(buf)-1);
+			buf[len] = 0;
+
+			/* exit on error */
+			if (len < 0) {
+				fprintf(stderr, "Error reading command: %s\n", strerror(errno));
+				exit(1);
+			}
+
+			/* strip CR/LF at EOL */
+			while (len>0 && (buf[strlen(buf)-1] == '\n' || buf[strlen(buf)-1] == '\r')) {
+				buf[strlen(buf)-1] = 0;
+				len--;
+			}
+
+			/* continue if no command */
+			if (len == 0)
+				continue;