Cleanup in elf.c with .bss section clean; adm command mounts cdrom instead of floppy...
[ZeXOS.git] / apps / play / main.c
blob2cfd62862a61b3ad9e3372e021093ba7623cbfe4
1 /*
2 * ZeX/OS
3 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <snd/audio.h>
26 #define KB_ESC 1
27 #define RIFF_MAGIC 0x46464952
28 #define WAVE_MAGIC 0x20746d66
29 #define DATA_MAGIC 0x61746164
31 /* RIFF header */
32 typedef struct {
33 unsigned chunkid;
34 unsigned chunksize;
35 unsigned format;
36 } riff_head_t;
38 /* WAVE header */
39 typedef struct {
40 unsigned subchunk1id;
41 unsigned subchunk1size;
42 unsigned short audioformat;
43 unsigned short numchannels;
44 unsigned samplerate;
45 unsigned byterate;
46 unsigned short blockalign;
47 unsigned short bitspersample;
48 } fmt_head_t;
50 /* DATA header */
51 typedef struct {
52 unsigned subchunk2id;
53 unsigned subchunk2size;
54 } data_head_t;
56 int main (int argc, char **argv)
58 printf ("play - The Wav Player\n");
60 if (argc <= 1) {
61 printf ("-> Please specify *.wav file to play\nSyntax: exec play <wavfile>\n");
62 return -1;
65 FILE *f = fopen (argv[1], "r");
67 if (!f) {
68 printf ("error -> file '%s' not found\n", argv[1]);
69 return -1;
72 fseek (f, 0, SEEK_END);
73 unsigned flen = ftell (f);
74 fseek (f, 0, SEEK_SET);
76 /* HACK: because of virtualbox & qemu ac'97 bug */
77 char *file = (char *) 0x400000;
79 if (!file)
80 return 0;
82 fread (file, flen, 1, f);
84 fclose (f);
86 riff_head_t *riff = (riff_head_t *) file;
87 fmt_head_t *fmt = (fmt_head_t *) ((char *) file + sizeof (riff_head_t));
88 data_head_t *data = (data_head_t *) ((char *) file + sizeof (riff_head_t) + sizeof (fmt_head_t));
90 if (riff->chunkid != RIFF_MAGIC) {
91 printf ("-> Wrong RIFF header magic: 0x%x, should be: 0x%x\n", riff->chunkid, RIFF_MAGIC);
92 goto clean;
95 if (fmt->subchunk1id != WAVE_MAGIC) {
96 printf ("-> Wrong WAVE header magic: 0x%x, should be: 0x%x\n", fmt->subchunk1id, WAVE_MAGIC);
97 goto clean;
100 if (data->subchunk2id != DATA_MAGIC) {
101 printf ("-> Wrong DATA header magic: 0x%x, should be: 0x%x\n", data->subchunk2id, DATA_MAGIC);
102 goto clean;
105 snd_cfg_t cfg;
106 cfg.dev = "/dev/ac97";
107 cfg.rate = fmt->samplerate;
108 cfg.format = SOUND_FORMAT_S16;
109 cfg.channels = fmt->numchannels;
111 snd_audio_t *aud = audio_open (&cfg);
113 if (!aud) {
114 printf ("Device is too busy\n");
115 goto clean;
118 audio_write (aud, file+44, flen-44);
120 printf ("Press ESC to stop playing\n");
122 for (; getkey () != KB_ESC; schedule ());
124 audio_close (aud);
125 clean:
126 free (file);
128 return 0;