4 #include <devices/ahi.h>
5 #include <exec/memory.h>
6 #include <libraries/ahi_sub.h>
7 #include <libraries/iffparse.h>
9 #include <proto/exec.h>
10 #include <proto/iffparse.h>
11 #include <proto/utility.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"
26 ProcessModeChunk( APTR
* buffer
, ULONG
* size
, ULONG
* new_board
);
38 } args
= { NULL
, NULL
, NULL
, FALSE
};
40 struct RDArgs
*rdargs
;
41 int rc
= RETURN_ERROR
;
43 rdargs
= ReadArgs( TEMPLATE
, (LONG
*) &args
, NULL
);
47 struct IFFHandle
* from
;
54 if( from
!= NULL
&& to
!= NULL
)
56 from
->iff_Stream
= (ULONG
) Open( args
.from
, MODE_OLDFILE
);
58 if( from
->iff_Stream
!= 0 )
62 error
= OpenIFF( from
, IFFF_READ
);
64 /* if( error == 0 ) */
66 /* error = PropChunk( from, ID_AHIM, ID_AUDM ); */
69 /* if( error == 0 ) */
71 /* error = PropChunk( from, ID_AHIM, ID_AUDN ); */
76 to
->iff_Stream
= (ULONG
) Open( args
.to
, MODE_NEWFILE
);
78 if( to
->iff_Stream
!= 0 )
82 error
= OpenIFF( to
, IFFF_WRITE
);
88 struct ContextNode
* cn
= NULL
;
90 error
= ParseIFF( from
, IFFPARSE_STEP
);
92 if( error
== 0 || error
== IFFERR_EOC
)
94 cn
= CurrentChunk( from
);
98 PrintFault( ERROR_OBJECT_NOT_FOUND
, "CurrentChunk()" );
102 if( cn
->cn_Type
!= ID_AHIM
)
104 Printf( "%s: Not an AHIM IFF file.\n", (ULONG
) args
.from
);
118 if( from
->iff_Depth
> 1 )
122 IDtoStr( cn
->cn_ID
, idbuf
);
124 Printf( "Processing %s (%ld bytes) ... ",
125 (ULONG
) idbuf
, cn
->cn_Size
);
129 buffer
= AllocVec( size
, MEMF_ANY
);
133 PrintFault( ERROR_NO_FREE_STORE
, idbuf
);
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
);
151 error
= PushChunk( to
,
152 cn
->cn_Type
, cn
->cn_ID
, IFFSIZE_UNKNOWN
);
155 if( from
->iff_Depth
> 1 )
159 error
= WriteChunkBytes( to
, buffer
, size
);
166 Printf( "%s: IFF error code %ld\n", (ULONG
)
167 (ULONG
) args
.to
, error
);
172 else if( error
== IFFERR_EOC
)
174 error
= PopChunk( to
);
178 Printf( "%s: IFF error code %ld\n", (ULONG
) args
.to
, error
);
182 if( from
->iff_Depth
> 1 && args
.verbose
)
187 else if( error
== IFFERR_EOF
)
199 Printf( "%ld\n", error
);
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
);
219 PrintFault( IoErr(), args
.to
);
224 Printf( "%s: IFF error code %ld\n", (ULONG
) (ULONG
) args
.from
, error
);
227 Close( (BPTR
) from
->iff_Stream
);
231 PrintFault( IoErr(), args
.from
);
242 PrintFault( IoErr(), "CloneAudioModes" );
249 ProcessModeChunk( APTR
* buffer
, ULONG
* size
, ULONG
* new_board
)
251 struct TagItem
* tstate
;
254 ULONG board
= new_board
== NULL
? 1 : *new_board
- 1;
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
)
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
)
309 *ptr
++ = tag
->ti_Data
;
317 while( *name
!= ':' && *name
!= 0 )
322 if( name
[ -2 ] == '-' && isdigit( name
[ -1 ] ) )
331 name_size
= sprintf( (char*) ptr
, "%s-%d:%s", card
, (int) board
+ 1, mode
);
337 *buffer
= new_buffer
;
338 *size
= tag_size
+ name_size
;
340 return new_buffer
!= NULL
;