grub2: bring back build of aros-side grub2 tools
[AROS.git] / workbench / devs / AHI / Examples / Extras / CloneAudioModes / CloneAudioModes.c
blob45e34572c6bf990cd3125ba739e9b876b012d8fc
2 #include <config.h>
4 #include <devices/ahi.h>
5 #include <exec/memory.h>
6 #include <libraries/ahi_sub.h>
7 #include <libraries/iffparse.h>
8 #include <proto/dos.h>
9 #include <proto/exec.h>
10 #include <proto/iffparse.h>
11 #include <proto/utility.h>
13 #include <stdio.h>
14 #include <ctype.h>
15 #include <string.h>
17 #include "version.h"
19 static const char version[] = "$VER: CloneAudioModes " VERS "\n\r";
21 long __oslibversion = 39;
23 #define TEMPLATE "FROM/A,TO/A,BOARD/N,VERBOSE/S"
25 BOOL
26 ProcessModeChunk( APTR* buffer, ULONG* size, ULONG* new_board );
29 int
30 main( void )
32 struct
34 STRPTR from;
35 STRPTR to;
36 ULONG* board;
37 ULONG verbose;
38 } args = { NULL, NULL, NULL, FALSE };
40 struct RDArgs *rdargs;
41 int rc = RETURN_ERROR;
43 rdargs = ReadArgs( TEMPLATE , (LONG *) &args, NULL );
45 if( rdargs != NULL )
47 struct IFFHandle* from;
48 struct IFFHandle* to;
49 LONG error;
51 from = AllocIFF();
52 to = AllocIFF();
54 if( from != NULL && to != NULL )
56 from->iff_Stream = (ULONG) Open( args.from, MODE_OLDFILE );
58 if( from->iff_Stream != 0 )
60 InitIFFasDOS( from );
62 error = OpenIFF( from, IFFF_READ );
64 /* if( error == 0 ) */
65 /* { */
66 /* error = PropChunk( from, ID_AHIM, ID_AUDM ); */
67 /* } */
69 /* if( error == 0 ) */
70 /* { */
71 /* error = PropChunk( from, ID_AHIM, ID_AUDN ); */
72 /* } */
74 if( error == 0 )
76 to->iff_Stream = (ULONG) Open( args.to, MODE_NEWFILE );
78 if( to->iff_Stream != 0 )
80 InitIFFasDOS( to );
82 error = OpenIFF( to, IFFF_WRITE );
84 if( error == 0 )
86 while( TRUE )
88 struct ContextNode* cn = NULL;
90 error = ParseIFF( from, IFFPARSE_STEP );
92 if( error == 0 || error == IFFERR_EOC )
94 cn = CurrentChunk( from );
96 if( cn == NULL )
98 PrintFault( ERROR_OBJECT_NOT_FOUND, "CurrentChunk()" );
99 break;
102 if( cn->cn_Type != ID_AHIM )
104 Printf( "%s: Not an AHIM IFF file.\n", (ULONG) args.from );
105 break;
110 if( error == 0 )
112 char idbuf[ 5 ];
113 APTR buffer;
114 ULONG size;
116 error = 0;
118 if( from->iff_Depth > 1 )
120 if( args.verbose )
122 IDtoStr( cn->cn_ID, idbuf );
124 Printf( "Processing %s (%ld bytes) ... ",
125 (ULONG) idbuf, cn->cn_Size );
128 size = cn->cn_Size;
129 buffer = AllocVec( size, MEMF_ANY );
131 if( buffer == NULL )
133 PrintFault( ERROR_NO_FREE_STORE, idbuf );
134 break;
137 error = ReadChunkBytes( from, buffer, size );
139 if( cn->cn_ID == ID_AUDM )
141 if( ! ProcessModeChunk( &buffer, &size, args.board ) )
143 PrintFault( ERROR_NO_FREE_STORE, idbuf );
144 break;
149 if( error >= 0 )
151 error = PushChunk( to,
152 cn->cn_Type, cn->cn_ID, IFFSIZE_UNKNOWN );
155 if( from->iff_Depth > 1 )
157 if( error >= 0 )
159 error = WriteChunkBytes( to, buffer, size );
162 FreeVec( buffer );
164 if( error < 0 )
166 Printf( "%s: IFF error code %ld\n", (ULONG)
167 (ULONG) args.to, error );
168 break;
172 else if( error == IFFERR_EOC )
174 error = PopChunk( to );
176 if( error != 0 )
178 Printf( "%s: IFF error code %ld\n", (ULONG) args.to, error );
179 break;
182 if( from->iff_Depth > 1 && args.verbose )
184 Printf( "OK.\n" );
187 else if( error == IFFERR_EOF )
189 if( args.verbose )
191 Printf( "Done!\n" );
194 rc = RETURN_OK;
195 break;
197 else
199 Printf( "%ld\n", error );
200 break;
202 } // while
204 else
206 Printf( "%s: IFF error code %ld\n", (ULONG) args.to, error );
209 Close( (BPTR) to->iff_Stream );
211 if( rc != RETURN_OK )
213 Printf( "Deleting destination file %s.\n", (ULONG) args.to );
214 DeleteFile( args.to );
217 else
219 PrintFault( IoErr(), args.to );
222 else
224 Printf( "%s: IFF error code %ld\n", (ULONG) (ULONG) args.from, error );
227 Close( (BPTR) from->iff_Stream );
229 else
231 PrintFault( IoErr(), args.from );
235 FreeIFF( from );
236 FreeIFF( to );
238 FreeArgs( rdargs );
240 else
242 PrintFault( IoErr(), "CloneAudioModes" );
245 return rc;
248 BOOL
249 ProcessModeChunk( APTR* buffer, ULONG* size, ULONG* new_board )
251 struct TagItem* tstate;
252 struct TagItem* tag;
254 ULONG board = new_board == NULL ? 1 : *new_board - 1;
256 char* name = NULL;
257 ULONG name_size = 0;
258 ULONG tag_size = 4;
260 APTR new_buffer;
261 ULONG* ptr;
263 tstate = *buffer;
265 while( ( tag = NextTagItem( &tstate ) ) )
267 tag_size += sizeof( struct TagItem );
269 if( tag->ti_Tag == AHIDB_AudioID )
271 if( new_board == NULL )
273 board = ( ( tag->ti_Data >> 12 ) & 15 ) + 1;
276 else if( tag->ti_Tag == AHIDB_Name )
278 name = tag->ti_Data + *buffer;
280 name_size = strlen( name ) + 1 + 2;
284 new_buffer = AllocVec( tag_size + name_size, MEMF_ANY );
286 if( new_buffer != NULL )
288 char* card;
289 char* mode;
291 ptr = new_buffer;
293 tstate = *buffer;
295 while( ( tag = NextTagItem( &tstate ) ) )
297 *ptr++ = tag->ti_Tag;
299 if( tag->ti_Tag == AHIDB_AudioID )
301 *ptr++ = ( tag->ti_Data & 0xffff0fff ) | ( board << 12 );
303 else if( tag->ti_Tag == AHIDB_Name )
305 *ptr++ = tag_size;
307 else
309 *ptr++ = tag->ti_Data;
313 *ptr++ = TAG_DONE;
315 card = name;
317 while( *name != ':' && *name != 0 )
319 name++;
322 if( name[ -2 ] == '-' && isdigit( name[ -1 ] ) )
324 name[ -2 ] = 0;
327 *name++ = 0;
329 mode = name;
331 name_size = sprintf( (char*) ptr, "%s-%d:%s", card, (int) board + 1, mode );
332 name_size += 1;
335 FreeVec( *buffer );
337 *buffer = new_buffer;
338 *size = tag_size + name_size;
340 return new_buffer != NULL;