source: contrib/API/tools/testspdf.c@ 742

Last change on this file since 742 was 578, checked in by David Azarewicz, 11 years ago

API updates

File size: 9.6 KB
Line 
1#define INCL_DOS
2#define INCL_DOSERRORS
3#include <os2.h>
4#include <stdlib.h>
5#include <stdio.h>
6#include <io.h>
7#include <fcntl.h>
8#include <conio.h>
9#include <math.h>
10
11#include "uniaud.h"
12#include "unidef.h"
13#include "unierrno.h"
14
15
16int pcms_num[MAX_CARDS] = {0}; // number of pcm instances
17int cards_num = 0; // number of cards
18
19POSS32_DEVCAPS pcmcaps[MAX_CARDS] = {0}; // pointer to pcm caps
20
21UniaudCardInfo *CardInfo[MAX_CARDS] = {0};
22
23snd_pcm_status_t status;
24
25struct frmsize_s
26{
27 uint16_t bit_rate;
28 uint16_t frm_size[3];
29};
30
31static const struct frmsize_s frmsizecod_tbl[64] =
32{
33 { 32 ,{64 ,69 ,96 } },
34 { 32 ,{64 ,70 ,96 } },
35 { 40 ,{80 ,87 ,120 } },
36 { 40 ,{80 ,88 ,120 } },
37 { 48 ,{96 ,104 ,144 } },
38 { 48 ,{96 ,105 ,144 } },
39 { 56 ,{112 ,121 ,168 } },
40 { 56 ,{112 ,122 ,168 } },
41 { 64 ,{128 ,139 ,192 } },
42 { 64 ,{128 ,140 ,192 } },
43 { 80 ,{160 ,174 ,240 } },
44 { 80 ,{160 ,175 ,240 } },
45 { 96 ,{192 ,208 ,288 } },
46 { 96 ,{192 ,209 ,288 } },
47 { 112 ,{224 ,243 ,336 } },
48 { 112 ,{224 ,244 ,336 } },
49 { 128 ,{256 ,278 ,384 } },
50 { 128 ,{256 ,279 ,384 } },
51 { 160 ,{320 ,348 ,480 } },
52 { 160 ,{320 ,349 ,480 } },
53 { 192 ,{384 ,417 ,576 } },
54 { 192 ,{384 ,418 ,576 } },
55 { 224 ,{448 ,487 ,672 } },
56 { 224 ,{448 ,488 ,672 } },
57 { 256 ,{512 ,557 ,768 } },
58 { 256 ,{512 ,558 ,768 } },
59 { 320 ,{640 ,696 ,960 } },
60 { 320 ,{640 ,697 ,960 } },
61 { 384 ,{768 ,835 ,1152 } },
62 { 384 ,{768 ,836 ,1152 } },
63 { 448 ,{896 ,975 ,1344 } },
64 { 448 ,{896 ,976 ,1344 } },
65 { 512 ,{1024 ,1114 ,1536 } },
66 { 512 ,{1024 ,1115 ,1536 } },
67 { 576 ,{1152 ,1253 ,1728 } },
68 { 576 ,{1152 ,1254 ,1728 } },
69 { 640 ,{1280 ,1393 ,1920 } },
70 { 640 ,{1280 ,1394 ,1920 } }
71};
72
73
74int main (int argc, char *argv[])
75{
76 int ver, err, ret;
77 int bytesread, count, blocksize;
78 int card_id = 0;
79 uniaud_pcm *pcm = NULL;
80 char *Buffer;
81 char *out_buf;
82 int readed, written, state, fsize;
83 FILE *input_handle = NULL;
84 unsigned int syncword, crc1, fscod,frmsizecod,bsid,bsmod,frame_size;
85 uint16_t *out_buf16;
86
87 printf("SPDIF test tool for UNIAUD. Version 0.01\n");
88 printf("Copyright 2007 by Vlad Stelmahosky aka Vladest\n");
89
90 ver = uniaud_get_version();
91
92 switch (ver)
93 {
94 case -2:
95 printf("Error: uniaud not detected\n");
96 return 1;
97 break;
98 case -1:
99 printf("Error: uniaud error\n");
100 return 1;
101 break;
102 default:
103 if (ver < 111)
104 {
105 printf("Error: unsupported version of uniaud\n");
106 return 1;
107 } else
108 printf("Detected UNIAUD version %1d.%02d.%02d\n", ver/10000, (ver / 100) % 100, ver % 100 );
109 }
110
111 cards_num = uniaud_get_cards();
112 if (!cards_num)
113 {
114 printf("No audio cards detected\n");
115 return 1;
116 }
117
118 printf("Detected %i audio adapter(s)\n", cards_num);
119
120 // set pcm to ON
121 if (uniaud_mixer_put_value_by_name(card_id,"IEC958 Playback Switch",1, 0, 0) < 0)
122 {
123 printf("Error setting IEC958 Playback switch\n");
124 }
125 if (uniaud_mixer_put_value_by_name(card_id,"IEC958 Playback AC97-SPSA",0, 0, 0) < 0)
126 {
127 printf("Error setting IEC958 Playback AC97\n");
128 }
129 /*
130 * AES settings:
131 * AES0 # consumer, not-copyright, emphasis-none, mode=0
132 * default 0x04
133 * AES1 # original, PCM coder
134 * default 0x82
135 * AES2 # source and channel
136 * default 0x00
137 * AES3 # fs=48000Hz, clock accuracy=1000ppm
138 * default 0x02
139 */
140#if 1
141 if (uniaud_mixer_put_spdif_status(card_id,
142 "IEC958 Playback Default",
143 IEC958_AES0_PROFESSIONAL |
144 IEC958_AES0_NONAUDIO |
145 IEC958_AES0_PRO_EMPHASIS_NONE |
146 IEC958_AES0_PRO_FS_48000,
147 IEC958_AES1_PRO_MODE_NOTID |
148 IEC958_AES1_PRO_USERBITS_NOTID,
149 IEC958_AES2_PRO_WORDLEN_NOTID,
150 0
151 /*0x06, 0x82, 0x00, 0x02*/))
152#else
153 if (uniaud_mixer_put_spdif_status(card_id,
154 "IEC958 Playback Default",
155 IEC958_AES0_CON_EMPHASIS_NONE
156 | IEC958_AES0_NONAUDIO,
157 IEC958_AES1_CON_ORIGINAL |
158 IEC958_AES1_CON_PCM_CODER,
159 0,
160 IEC958_AES3_CON_FS_48000
161 /*0x06, 0x82, 0x00, 0x02*/))
162
163#endif
164 {
165 printf("Error setting IEC958 status\n");
166 }
167#if 0
168 if (uniaud_mixer_put_value_by_name(card_id,"Master Playback Switch",1, 0, 0) < 0)
169 {
170 printf("Error in mixer\n");
171 }
172 if (uniaud_mixer_put_value_by_name(card_id,"Master Playback Volume",50, 0, 0) < 0)
173 {
174 printf("Error in mixer\n");
175 }
176 if (uniaud_mixer_put_value_by_name(card_id,"Master Playback Volume",50, 1, 0) < 0)
177 {
178 printf("Error in mixer\n");
179 }
180
181 if (uniaud_mixer_put_value_by_name(card_id,"PCM Playback Switch",1, 0, 0) < 0)
182 {
183 printf("Error in mixer\n");
184 }
185 if (uniaud_mixer_put_value_by_name(card_id,"PCM Playback Volume",31, 0, 0) < 0)
186 {
187 printf("Error in mixer\n");
188 }
189 if (uniaud_mixer_put_value_by_name(card_id,"PCM Playback Volume",31, 1, 0) < 0)
190 {
191 printf("Error in mixer\n");
192 }
193#endif
194 readed = written = 0;
195 /* PCM N2 = SPDIF */
196 err = uniaud_pcm_open(card_id, PCM_TYPE_WRITE, 0, 0, 48000, 2,
197 SNDRV_PCM_FORMAT_S16_LE, &pcm);
198 if (pcm && err == 0)
199 {
200 printf("opened. pcm = %x\n", pcm);
201 err = uniaud_pcm_prepare(pcm);
202 printf("prepare err = %i\n", err);
203 uniaud_pcm_status(pcm, &status);
204 if (argc > 1)
205 input_handle = fopen(argv[1], "rb");
206 if (!input_handle)
207 {
208 err = uniaud_pcm_close(pcm);
209 printf("Error opening file\n");
210 return 0;
211 }
212 //count = pcm->bufsize;
213 count = pcm->period_size*2;
214 fseek(input_handle, 0L, SEEK_END);
215 fsize = ftell(input_handle);
216 fseek(input_handle, 0L, SEEK_SET);
217 blocksize = 1792; /* AC3 block size*/
218 Buffer = malloc(65535);
219 out_buf = malloc(65535);
220 // memset(Buffer,0, count);
221
222 while (1)
223 {
224 bytesread = fread (Buffer, 1, blocksize, input_handle);
225 // read file and play into driver
226 if (bytesread != blocksize) break;
227 syncword = Buffer[0] | (Buffer[1] << 8);
228 crc1 = Buffer[2] | (Buffer[3] << 8);
229 fscod = (Buffer[4] >> 6) & 0x3;
230 frmsizecod = Buffer[4] & 0x3f;
231 bsid = (Buffer[5] >> 3) & 0x1f;
232 bsmod = Buffer[5] & 0x7; /* bsmod, stream = 0 */
233 frame_size = frmsizecod_tbl[frmsizecod].frm_size[fscod] ;
234
235 //printf("AC3 frame size: %i, period: %i\n", frame_size, pcm->period_size);
236 out_buf16 = (uint16_t *)out_buf;
237 out_buf16[0] = 0xF872; // iec 61937 syncword 1
238 out_buf16[1] = 0x4E1F; // iec 61937 syncword 2
239 out_buf16[2] = 0x0001; // data-type ac3
240 out_buf16[2] |= (Buffer[5] & 0x7) << 8; // bsmod
241 out_buf16[3] = (frame_size *2 ) << 3; // ???? number of bits in payload
242 //out_buf[8] = 0x77; out_buf[9] = 0x0b; // AC3 syncwork
243 swab(Buffer, &out_buf[8], frame_size*2);
244 //memcpy(&out_buf[8], Buffer, frame_size*2);
245
246 err = uniaud_pcm_write(pcm, out_buf, pcm->period_size*2);
247
248 ret = uniaud_pcm_wait(pcm, 1000);
249 if (ret <= 0)
250 printf("error waiting pcm interrupt %i\n", ret);
251
252 if (err > 0) // write something
253 {
254 written=written+err;
255 printf("written=%i. AC3 frame size: %i, fscod: %i\r",written, frame_size, fscod);
256 if (written >= fsize) break;
257 }
258 if (err == -EAGAIN) //
259 {
260// printf("eagain\n");
261 continue;
262 }
263 if (err < 0) {
264 if (err < -10000)
265 {
266 printf("internal uniaud err = %i\n", err);
267 break;
268 }
269 state = uniaud_pcm_state(pcm);
270 printf("state after write: %i, err = %i\n",state, err);
271 if ( (state != SND_PCM_STATE_PREPARED) &&
272 (state != SND_PCM_STATE_RUNNING) &&
273 (state != SND_PCM_STATE_DRAINING) ) {
274 printf("write:BAD STATE2, state = %d, going to try XRUN\n",state);
275 if ((ret = uniaud_pcm_prepare(pcm))<0) {
276// printf("xrun: prepare error: %i", err);
277 return 0;
278 }
279 }
280 }
281 }
282 fclose(input_handle);
283 free(Buffer);
284 free(out_buf);
285 err = uniaud_pcm_close(pcm);
286 }
287 else
288 {
289 printf("open err: %i, pcm %x\n", err, pcm);
290 if (err == 10005)
291 err = uniaud_pcm_close(pcm);
292 printf("close err: %i\n", err);
293 }
294
295 return 0;
296}
Note: See TracBrowser for help on using the repository browser.