1 /* Simple sample player for AHI using the low-level API
2 with double buffered AHIST_DYNAMICSAMPLE sounds.
4 Usage: DoubleBuffer < [raw sample file]
6 the file must be in mono 16 bit signed big endian format sampled
9 This software is Public Domain. */
11 #include <devices/ahi.h>
12 #include <exec/exec.h>
13 #include <proto/ahi.h>
14 #include <proto/dos.h>
15 #include <proto/exec.h>
18 #define MINBUFFLEN 10000
20 struct Library
*AHIBase
;
21 struct MsgPort
*AHImp
=NULL
;
22 struct AHIRequest
*AHIio
=NULL
;
27 struct AHIAudioModeRequester
*req
=NULL
;
28 struct AHIAudioCtrl
*actrl
=NULL
;
30 BOOL DBflag
=FALSE
; // double buffer flag
33 struct AHISampleInfo Sample0
=
40 struct AHISampleInfo Sample1
=
47 __asm __saveds ULONG
SoundFunc(register __a0
struct Hook
*hook
,
48 register __a2
struct AHIAudioCtrl
*actrl
,
49 register __a1
struct AHISoundMessage
*smsg
)
51 if(DBflag
= !DBflag
) // Flip and test
52 AHI_SetSound(0,1,0,0,actrl
,NULL
);
54 AHI_SetSound(0,0,0,0,actrl
,NULL
);
55 Signal(actrl
->ahiac_UserData
,(1L<<signal
));
59 struct Hook SoundHook
=
70 ULONG mixfreq
,playsamples
,readsamples
,signals
,i
;
72 if(AHImp
=CreateMsgPort())
74 if(AHIio
=(struct AHIRequest
*)CreateIORequest(AHImp
,sizeof(struct AHIRequest
)))
76 AHIio
->ahir_Version
= 4; // Open at least version 4 of 'ahi.device'.
77 if(!(AHIDevice
=OpenDevice(AHINAME
,AHI_NO_UNIT
,(struct IORequest
*)AHIio
,NULL
)))
79 AHIBase
=(struct Library
*)AHIio
->ahir_Std
.io_Device
;
81 if(req
=AHI_AllocAudioRequest(
82 AHIR_PubScreenName
,"",
83 AHIR_TitleText
,"Select a mode and rate",
84 AHIR_InitialMixFreq
,17640,
88 if(AHI_AudioRequest(req
,TAG_DONE
))
90 if(actrl
=AHI_AllocAudio(
91 AHIA_AudioID
,req
->ahiam_AudioID
,
92 AHIA_MixFreq
,req
->ahiam_MixFreq
,
95 AHIA_SoundFunc
,&SoundHook
,
96 AHIA_UserData
,FindTask(NULL
),
99 AHI_GetAudioAttrs(AHI_INVALID_ID
,actrl
,
100 AHIDB_MaxPlaySamples
,&playsamples
,
102 AHI_ControlAudio(actrl
,
103 AHIC_MixFreq_Query
,&mixfreq
,
105 BufferLen
=playsamples
*17640/mixfreq
;
106 if (BufferLen
<MINBUFFLEN
)
107 BufferLen
=MINBUFFLEN
;
109 Sample0
.ahisi_Length
=BufferLen
;
110 Sample1
.ahisi_Length
=BufferLen
;
111 Sample0
.ahisi_Address
=AllocVec(BufferLen
*2,MEMF_PUBLIC
|MEMF_CLEAR
);
112 Sample1
.ahisi_Address
=AllocVec(BufferLen
*2,MEMF_PUBLIC
|MEMF_CLEAR
);
114 if(Sample0
.ahisi_Address
&& Sample1
.ahisi_Address
)
116 if((!(AHI_LoadSound(0,AHIST_DYNAMICSAMPLE
,&Sample0
,actrl
))) &&
117 (!(AHI_LoadSound(1,AHIST_DYNAMICSAMPLE
,&Sample1
,actrl
))))
119 if((signal
=AllocSignal(-1)) != -1)
121 if(!(AHI_ControlAudio(actrl
,
125 // Everything is set up now. Let's load the buffers and start rockin'...
126 Read(Input(),Sample0
.ahisi_Address
,BufferLen
*2);
128 // The new AHI_PlayA() function is demonstrated...
137 AHIP_EndChannel
,NULL
,
139 /* These functions were available in V2, too.
140 AHI_SetFreq(0,17640,actrl,AHISF_IMM);
141 AHI_SetVol(0,0x10000L,0x8000L,actrl,AHISF_IMM);
142 AHI_SetSound(0,0,0,0,actrl,AHISF_IMM);
146 signals
=Wait((1L<<signal
) | SIGBREAKF_CTRL_C
);
147 if(signals
& SIGBREAKF_CTRL_C
)
152 readsamples
=Read(Input(),Sample1
.ahisi_Address
,BufferLen
*2)/2;
153 if(readsamples
<BufferLen
)
155 // Clear rest of buffer
156 for(i
=readsamples
;i
<BufferLen
;i
++)
157 ((WORD
*)Sample1
.ahisi_Address
)[i
]=0;
159 // Clear other buffer
160 for(i
=0;i
<BufferLen
;i
++)
161 ((WORD
*)Sample0
.ahisi_Address
)[i
]=0;
167 readsamples
=Read(Input(),Sample0
.ahisi_Address
,BufferLen
*2)/2;
168 if(readsamples
<BufferLen
)
170 // Clear rest of buffer
171 for(i
=readsamples
;i
<BufferLen
;i
++)
172 ((WORD
*)Sample0
.ahisi_Address
)[i
]=0;
174 // Clear other buffer
175 for(i
=0;i
<BufferLen
;i
++)
176 ((WORD
*)Sample1
.ahisi_Address
)[i
]=0;
183 if(signals
& SIGBREAKF_CTRL_C
)
184 Printf("***Break\n");
186 Wait(1L<<signal
); // Wait for half-loaded buffer to finish.
188 AHI_ControlAudio(actrl
,
198 Printf("Cannot intialize sample buffers\n");
201 Printf("Out of memory.\n");
203 FreeVec(Sample0
.ahisi_Address
);
204 FreeVec(Sample1
.ahisi_Address
);
205 Sample0
.ahisi_Address
=NULL
;
206 Sample1
.ahisi_Address
=NULL
;
207 AHI_FreeAudio(actrl
);
211 Printf("Unable to allocate sound hardware\n");
216 Printf("Aborted.\n");
217 else if(IoErr() EQ ERROR_NO_MORE_ENTRIES
)
218 Printf("No available audio modes.\n");
219 else if(IoErr() EQ ERROR_NO_FREE_STORE
)
220 Printf("Out of memory.\n");
223 AHI_FreeAudioRequest(req
);
227 Printf("Out of memory.\n");
229 CloseDevice((struct IORequest
*)AHIio
);
230 AHIDevice
=-1; // Good habit, IMHO.
232 DeleteIORequest((struct IORequest
*)AHIio
);
235 DeleteMsgPort(AHImp
);