1 /* MPEG/WAVE Sound library
2 
3    (C) 1997 by Jung woo-jae */
4 
5 // Wavetoraw.cc
6 // Server which strips wave header.
7 
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11 
12 #include <stdlib.h>
13 
14 #ifdef HAVE_MALLOC_H
15 #  include <malloc.h>
16 #endif
17 
18 #include "mpegsound.h"
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 #ifdef __cplusplus
25 }
26 #endif
27 
28 #ifdef WORDS_BIGENDIAN
29 typedef union {
30     long arg;
31     char byte_represent[4];
32 } endian_hack_1;
33 
34 typedef union {
35     short arg;
36     char byte_represent[2];
37 } endian_hack_2;
38 
HOST_TO_LE16(short x)39 inline short HOST_TO_LE16(short x)
40 {
41     endian_hack_2 in,out;
42     in.arg=x;
43     out.arg=0;
44     out.byte_represent[0]=in.byte_represent[1];
45     out.byte_represent[1]=in.byte_represent[0];
46     return (short)out.arg;
47 }
HOST_TO_LE32(int x)48 inline int HOST_TO_LE32(int x)
49 {
50     endian_hack_1 in,out;
51     in.arg=x;
52     out.arg=0;
53     out.byte_represent[0]=in.byte_represent[3];
54     out.byte_represent[1]=in.byte_represent[2];
55     out.byte_represent[2]=in.byte_represent[1];
56     out.byte_represent[3]=in.byte_represent[0];
57     return out.arg;
58 }
59 
60 #else
61 #define HOST_TO_LE16(x)  (x)
62 #define HOST_TO_LE32(x)  (x)
63 #endif
Wavetoraw(Soundinputstream * loader,Soundplayer * player)64 Wavetoraw::Wavetoraw(Soundinputstream *loader,Soundplayer *player)
65 {
66   __errorcode=SOUND_ERROR_OK;
67   initialized=false;buffer=NULL;
68   this->loader=loader;this->player=player;
69 };
70 
~Wavetoraw()71 Wavetoraw::~Wavetoraw()
72 {
73   if (buffer)free(buffer);
74 };
75 
76 
77 // Convert wave format to raw format class
initialize(void)78 bool Wavetoraw::initialize(void)
79 {
80 	int c;
81 
82 	char tmpbuffer[1024];
83 	if ( !(c=loader->getblock(tmpbuffer,sizeof(WAVEHEADER))) )
84 	{
85 		return seterrorcode(SOUND_ERROR_FILEREADFAIL);
86 	}
87 
88 	if (!testwave(tmpbuffer))
89 		return false;
90 	//int ssize = (samplesize == 16 ? AFMT_S16_LE : AFMT_U8);
91 	if (!(player->setsoundtype(stereo, samplesize, speed)))
92 		return false;
93 
94   if (!buffer)
95   {
96     buffersize=player->getblocksize();
97 		if (buffersize < (int)sizeof(WAVEHEADER))
98 			buffersize = sizeof(WAVEHEADER);
99     if ((buffer=(char *)malloc(buffersize * sizeof(char)))==NULL)
100     {
101       return seterrorcode(SOUND_ERROR_MEMORYNOTENOUGH);
102     }
103   }
104 
105 	currentpoint=0;
106 	initialized=true;
107   return true;
108 }
109 
run(void)110 bool Wavetoraw::run(void)
111 {
112   int c;
113 
114 	c=loader->getblock(buffer,buffersize);
115 	if (c==0)
116 	{
117 		return seterrorcode(SOUND_ERROR_FILEREADFAIL);
118 	}
119 
120 	currentpoint+=c;
121 	if (player->putblock(buffer,buffersize) == false)
122 		return false;
123 
124 	if (currentpoint >= size)
125 	{
126 		return seterrorcode(SOUND_ERROR_FINISH);
127 	}
128 
129   return true;
130 }
131 
setcurrentpoint(int p)132 void Wavetoraw::setcurrentpoint(int p)
133 {
134   if (p*pcmsize>size)currentpoint=size;
135   else currentpoint=p*pcmsize;
136   loader->setposition(currentpoint+sizeof(WAVEHEADER));
137 }
138 
testwave(char * buffer)139 bool Wavetoraw::testwave(char *buffer)
140 {
141   WAVEHEADER *tmp = (WAVEHEADER *)buffer;
142 
143 	if (tmp->main_chunk==RIFF && tmp->chunk_type==WAVE &&
144 		tmp->sub_chunk==FMT && tmp->data_chunk==DATA)
145 	{
146 		if (tmp->format == PCM_CODE && (tmp->modus == WAVE_STEREO ||
147 			tmp->modus == WAVE_MONO))
148 		{
149 			stereo = (tmp->modus==WAVE_STEREO) ? 1 : 0;
150 			samplesize = HOST_TO_LE16((int)(tmp->bit_p_spl));
151 			speed = HOST_TO_LE32((int)(tmp->sample_fq));
152 			size = HOST_TO_LE32((int)(tmp->data_length));
153 			pcmsize=1;
154 			if (stereo == 1)
155 				pcmsize *= 2;
156 			if (samplesize == 16)
157 				pcmsize*=2;
158 			return true;
159 		}
160 	}
161 
162 	return seterrorcode(SOUND_ERROR_BAD);
163 }
164 
165