~ubuntu-branches/ubuntu/saucy/dahdi-tools/saucy-proposed

« back to all changes in this revision

Viewing changes to xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_playout_buf.c

  • Committer: Package Import Robot
  • Author(s): Jackson Doak
  • Date: 2013-08-25 12:48:37 UTC
  • mfrom: (2.1.7 sid)
  • Revision ID: package-import@ubuntu.com-20130825124837-wtefi7f9dsihg8is
Tags: 1:2.7.0-1ubuntu1
* Merge from debian. Remaining changes:
  - debian/control: Added gawk as dependency for dkms build
  - debian/control: Package dahdi Depends on dahdi-dkms | dahdi-source
  - debian/control: Set ubuntu maintainer    
  - added debian/dahdi.postinst
  - debian/control: Removed Uploaders field.
  - added debian/dahdi.postinst
  - added --error-handler=init_failed to debian/rules
  

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
2
 
 
3
File: oct6100_playout_buf.c
 
4
 
 
5
    Copyright (c) 2001-2007 Octasic Inc.
 
6
    
 
7
Description: 
 
8
 
 
9
        This file contains functions used to manage buffer playout.
 
10
 
 
11
This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API  is 
 
12
free software; you can redistribute it and/or modify it under the terms of 
 
13
the GNU General Public License as published by the Free Software Foundation; 
 
14
either version 2 of the License, or (at your option) any later version.
 
15
 
 
16
The OCT6100 GPL API is distributed in the hope that it will be useful, but 
 
17
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 
18
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
 
19
for more details. 
 
20
 
 
21
You should have received a copy of the GNU General Public License 
 
22
along with the OCT6100 GPL API; if not, write to the Free Software 
 
23
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 
24
 
 
25
$Octasic_Release: OCT612xAPI-01.00-PR49 $
 
26
 
 
27
$Octasic_Revision: 109 $
 
28
 
 
29
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
30
 
 
31
 
 
32
/*****************************  INCLUDE FILES  *******************************/
 
33
 
 
34
#include "octdef.h"
 
35
 
 
36
#include "oct6100api/oct6100_defines.h"
 
37
#include "oct6100api/oct6100_errors.h"
 
38
#include "oct6100api/oct6100_apiud.h"
 
39
 
 
40
#include "apilib/octapi_llman.h"
 
41
 
 
42
#include "oct6100api/oct6100_tlv_inst.h"
 
43
#include "oct6100api/oct6100_chip_open_inst.h"
 
44
#include "oct6100api/oct6100_chip_stats_inst.h"
 
45
#include "oct6100api/oct6100_interrupts_inst.h"
 
46
#include "oct6100api/oct6100_remote_debug_inst.h"
 
47
#include "oct6100api/oct6100_debug_inst.h"
 
48
#include "oct6100api/oct6100_api_inst.h"
 
49
#include "oct6100api/oct6100_channel_inst.h"
 
50
#include "oct6100api/oct6100_playout_buf_inst.h"
 
51
 
 
52
#include "oct6100api/oct6100_interrupts_pub.h"
 
53
#include "oct6100api/oct6100_chip_open_pub.h"
 
54
#include "oct6100api/oct6100_channel_pub.h"
 
55
#include "oct6100api/oct6100_events_pub.h"
 
56
#include "oct6100api/oct6100_playout_buf_pub.h"
 
57
 
 
58
#include "oct6100_chip_open_priv.h"
 
59
#include "oct6100_miscellaneous_priv.h"
 
60
#include "oct6100_memory_priv.h"
 
61
#include "oct6100_channel_priv.h"
 
62
#include "oct6100_events_priv.h"
 
63
#include "oct6100_playout_buf_priv.h"
 
64
 
 
65
/****************************  PUBLIC FUNCTIONS  *****************************/
 
66
 
 
67
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
68
 
 
69
Function:               Oct6100BufferPlayoutLoad
 
70
 
 
71
Description:    This function loads a playout buffer into external memory.
 
72
 
 
73
-------------------------------------------------------------------------------
 
74
|       Argument                |       Description
 
75
-------------------------------------------------------------------------------
 
76
f_pApiInstance                  Pointer to API instance. This memory is used to keep the
 
77
                                                present state of the chip and all its resources.
 
78
 
 
79
f_pBufferLoad                   Pointer to buffer playout load structure.
 
80
 
 
81
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
82
#if !SKIP_Oct6100BufferPlayoutLoadDef
 
83
UINT32 Oct6100BufferPlayoutLoadDef(
 
84
                                tPOCT6100_BUFFER_LOAD                   f_pBufferLoad )
 
85
{
 
86
        f_pBufferLoad->pbyBufferPattern = NULL;
 
87
        f_pBufferLoad->ulBufferSize = 128;
 
88
        f_pBufferLoad->ulBufferPcmLaw = cOCT6100_PCM_U_LAW;
 
89
        
 
90
        f_pBufferLoad->pulBufferIndex = NULL;
 
91
        f_pBufferLoad->pulPlayoutFreeMemSize = NULL;
 
92
 
 
93
        return cOCT6100_ERR_OK;
 
94
}
 
95
#endif
 
96
 
 
97
#if !SKIP_Oct6100BufferPlayoutLoad
 
98
UINT32 Oct6100BufferPlayoutLoad(
 
99
                                tPOCT6100_INSTANCE_API                          f_pApiInstance,
 
100
                                tPOCT6100_BUFFER_LOAD                           f_pBufferLoad )
 
101
{
 
102
        tOCT6100_SEIZE_SERIALIZE_OBJECT         SeizeSerObj;
 
103
        tOCT6100_RELEASE_SERIALIZE_OBJECT       ReleaseSerObj;
 
104
        UINT32                                                          ulSerRes = cOCT6100_ERR_OK;
 
105
        UINT32                                                          ulFncRes = cOCT6100_ERR_OK;
 
106
 
 
107
        /* Set the process context of the serialize structure. */
 
108
        SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext;
 
109
        ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext;
 
110
 
 
111
        /* Seize all list semaphores needed by this function. */
 
112
        SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
 
113
        SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY;
 
114
        ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj );
 
115
        if ( ulSerRes == cOCT6100_ERR_OK )
 
116
        {
 
117
                /* Call the serialized function. */
 
118
                ulFncRes = Oct6100BufferLoadSer( f_pApiInstance, f_pBufferLoad, TRUE, cOCT6100_INVALID_INDEX );
 
119
        }
 
120
        else
 
121
        {
 
122
                return ulSerRes;
 
123
        }
 
124
 
 
125
        /* Release the seized semaphores. */
 
126
        ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
 
127
        ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj );
 
128
 
 
129
        /* If an error occured then return the error code. */
 
130
        if ( ulSerRes != cOCT6100_ERR_OK )
 
131
                return ulSerRes;
 
132
        if ( ulFncRes != cOCT6100_ERR_OK )
 
133
                return ulFncRes;
 
134
 
 
135
        return cOCT6100_ERR_OK;
 
136
}
 
137
#endif
 
138
 
 
139
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
140
 
 
141
Function:               Oct6100BufferPlayoutLoadBlockInit
 
142
 
 
143
Description:    This function allows the user to initialize loading a buffer 
 
144
                                into external memory using blocks.
 
145
 
 
146
-------------------------------------------------------------------------------
 
147
|       Argument                |       Description
 
148
-------------------------------------------------------------------------------
 
149
f_pApiInstance                  Pointer to API instance. This memory is used to keep 
 
150
                                                the present state of the chip and all its resources.
 
151
 
 
152
f_pBufferLoadBlockInit  Pointer to buffer playout load block init structure.
 
153
 
 
154
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
155
#if !SKIP_Oct6100BufferPlayoutLoadBlockInitDef
 
156
UINT32 Oct6100BufferPlayoutLoadBlockInitDef(
 
157
                                tPOCT6100_BUFFER_LOAD_BLOCK_INIT        f_pBufferLoadBlockInit )
 
158
{
 
159
        f_pBufferLoadBlockInit->ulBufferSize = 128;
 
160
        f_pBufferLoadBlockInit->ulBufferPcmLaw = cOCT6100_PCM_U_LAW;
 
161
        
 
162
        f_pBufferLoadBlockInit->pulBufferIndex = NULL;
 
163
        f_pBufferLoadBlockInit->pulPlayoutFreeMemSize = NULL;
 
164
 
 
165
        return cOCT6100_ERR_OK;
 
166
}
 
167
#endif
 
168
 
 
169
#if !SKIP_Oct6100BufferPlayoutLoadBlockInit
 
170
UINT32 Oct6100BufferPlayoutLoadBlockInit(
 
171
                                tPOCT6100_INSTANCE_API                          f_pApiInstance,
 
172
                                tPOCT6100_BUFFER_LOAD_BLOCK_INIT        f_pBufferLoadBlockInit )
 
173
{
 
174
        tOCT6100_SEIZE_SERIALIZE_OBJECT         SeizeSerObj;
 
175
        tOCT6100_RELEASE_SERIALIZE_OBJECT       ReleaseSerObj;
 
176
        UINT32                                                          ulSerRes = cOCT6100_ERR_OK;
 
177
        UINT32                                                          ulFncRes = cOCT6100_ERR_OK;
 
178
 
 
179
        /* Set the process context of the serialize structure.*/
 
180
        SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext;
 
181
        ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext;
 
182
 
 
183
        /* Seize all list semaphores needed by this function. */
 
184
        SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
 
185
        SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY;
 
186
        ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj );
 
187
        if ( ulSerRes == cOCT6100_ERR_OK )
 
188
        {
 
189
                /* Call the serialized function. */
 
190
                ulFncRes = Oct6100BufferLoadBlockInitSer( f_pApiInstance, f_pBufferLoadBlockInit );
 
191
        }
 
192
        else
 
193
        {
 
194
                return ulSerRes;
 
195
        }
 
196
 
 
197
        /* Release the seized semaphores. */
 
198
        ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
 
199
        ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj );
 
200
 
 
201
        /* If an error occured then return the error code. */
 
202
        if ( ulSerRes != cOCT6100_ERR_OK )
 
203
                return ulSerRes;
 
204
        if ( ulFncRes != cOCT6100_ERR_OK )
 
205
                return ulFncRes;
 
206
 
 
207
        return cOCT6100_ERR_OK;
 
208
}
 
209
#endif
 
210
 
 
211
 
 
212
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
213
 
 
214
Function:               Oct6100BufferPlayoutLoadBlock
 
215
 
 
216
Description:    This function allows the user to load a buffer block into 
 
217
                                external memory.
 
218
 
 
219
-------------------------------------------------------------------------------
 
220
|       Argument                |       Description
 
221
-------------------------------------------------------------------------------
 
222
f_pApiInstance                  Pointer to API instance. This memory is used to keep 
 
223
                                                the present state of the chip and all its resources.
 
224
 
 
225
f_pBufferLoadBlock              Pointer to buffer playout load block structure.
 
226
 
 
227
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
228
#if !SKIP_Oct6100BufferPlayoutLoadBlockDef
 
229
UINT32 Oct6100BufferPlayoutLoadBlockDef(
 
230
                                tPOCT6100_BUFFER_LOAD_BLOCK             f_pBufferLoadBlock )
 
231
{
 
232
        f_pBufferLoadBlock->ulBufferIndex = cOCT6100_INVALID_VALUE;
 
233
        f_pBufferLoadBlock->ulBlockLength = cOCT6100_INVALID_VALUE;
 
234
        f_pBufferLoadBlock->ulBlockOffset = cOCT6100_INVALID_VALUE;
 
235
        
 
236
        f_pBufferLoadBlock->pbyBufferPattern = NULL;
 
237
 
 
238
        return cOCT6100_ERR_OK;
 
239
}
 
240
#endif
 
241
 
 
242
#if !SKIP_Oct6100BufferPlayoutLoadBlock
 
243
UINT32 Oct6100BufferPlayoutLoadBlock(
 
244
                                tPOCT6100_INSTANCE_API                          f_pApiInstance,
 
245
                                tPOCT6100_BUFFER_LOAD_BLOCK                     f_pBufferLoadBlock )
 
246
{
 
247
        tOCT6100_SEIZE_SERIALIZE_OBJECT         SeizeSerObj;
 
248
        tOCT6100_RELEASE_SERIALIZE_OBJECT       ReleaseSerObj;
 
249
        UINT32                                                          ulSerRes = cOCT6100_ERR_OK;
 
250
        UINT32                                                          ulFncRes = cOCT6100_ERR_OK;
 
251
 
 
252
        /* Set the process context of the serialize structure. */
 
253
        SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext;
 
254
        ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext;
 
255
 
 
256
        /* Seize all list semaphores needed by this function. */
 
257
        SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
 
258
        SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY;
 
259
        ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj );
 
260
        if ( ulSerRes == cOCT6100_ERR_OK )
 
261
        {
 
262
                /* Call the serialized function. */
 
263
                ulFncRes = Oct6100BufferLoadBlockSer( f_pApiInstance, f_pBufferLoadBlock );
 
264
        }
 
265
        else
 
266
        {
 
267
                return ulSerRes;
 
268
        }
 
269
 
 
270
        /* Release the seized semaphores. */
 
271
        ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
 
272
        ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj );
 
273
 
 
274
        /* If an error occured then return the error code. */
 
275
        if ( ulSerRes != cOCT6100_ERR_OK )
 
276
                return ulSerRes;
 
277
        if ( ulFncRes != cOCT6100_ERR_OK )
 
278
                return ulFncRes;
 
279
 
 
280
        return cOCT6100_ERR_OK;
 
281
}
 
282
#endif
 
283
 
 
284
 
 
285
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
286
 
 
287
Function:               Oct6100BufferPlayoutUnload
 
288
 
 
289
Description:    This function unloads a playout buffer from external memory.
 
290
 
 
291
-------------------------------------------------------------------------------
 
292
|       Argument                |       Description
 
293
-------------------------------------------------------------------------------
 
294
f_pApiInstance                  Pointer to API instance. This memory is used to keep the
 
295
                                                present state of the chip and all its resources.
 
296
 
 
297
f_pBufferUnload                 Pointer to buffer playout unload structure.
 
298
 
 
299
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
300
#if !SKIP_Oct6100BufferPlayoutUnloadDef
 
301
UINT32 Oct6100BufferPlayoutUnloadDef(
 
302
                                tPOCT6100_BUFFER_UNLOAD                 f_pBufferUnload )
 
303
{
 
304
        f_pBufferUnload->ulBufferIndex = cOCT6100_INVALID_VALUE;
 
305
 
 
306
        return cOCT6100_ERR_OK;
 
307
}
 
308
#endif
 
309
 
 
310
#if !SKIP_Oct6100BufferPlayoutUnload
 
311
UINT32 Oct6100BufferPlayoutUnload(
 
312
                                tPOCT6100_INSTANCE_API                  f_pApiInstance,
 
313
                                tPOCT6100_BUFFER_UNLOAD                 f_pBufferUnload )
 
314
{
 
315
        tOCT6100_SEIZE_SERIALIZE_OBJECT         SeizeSerObj;
 
316
        tOCT6100_RELEASE_SERIALIZE_OBJECT       ReleaseSerObj;
 
317
        UINT32                                                          ulSerRes = cOCT6100_ERR_OK;
 
318
        UINT32                                                          ulFncRes = cOCT6100_ERR_OK;
 
319
 
 
320
        /* Set the process context of the serialize structure. */
 
321
        SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext;
 
322
        ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext;
 
323
 
 
324
        /* Seize all list semaphores needed by this function. */
 
325
        SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
 
326
        SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY;
 
327
        ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj );
 
328
        if ( ulSerRes == cOCT6100_ERR_OK )
 
329
        {
 
330
                /* Call the serialized function. */
 
331
                ulFncRes = Oct6100BufferUnloadSer( f_pApiInstance, f_pBufferUnload, TRUE );
 
332
        }
 
333
        else
 
334
        {
 
335
                return ulSerRes;
 
336
        }
 
337
 
 
338
        /* Release the seized semaphores. */
 
339
        ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
 
340
        ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj );
 
341
 
 
342
        /* If an error occured then return the error code. */
 
343
        if ( ulSerRes != cOCT6100_ERR_OK )
 
344
                return ulSerRes;
 
345
        if ( ulFncRes != cOCT6100_ERR_OK )
 
346
                return ulFncRes;
 
347
 
 
348
        return cOCT6100_ERR_OK;
 
349
}
 
350
#endif
 
351
 
 
352
 
 
353
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
354
 
 
355
Function:               Oct6100BufferPlayoutAdd
 
356
 
 
357
Description:    This function adds a buffer to a port's playout list on the 
 
358
                                selected channel.
 
359
 
 
360
-------------------------------------------------------------------------------
 
361
|       Argument                |       Description
 
362
-------------------------------------------------------------------------------
 
363
f_pApiInstance                  Pointer to API instance. This memory is used to keep the
 
364
                                                present state of the chip and all its resources.
 
365
 
 
366
f_pBufferPlayoutAdd             Pointer to buffer playout add structure.
 
367
 
 
368
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
369
#if !SKIP_Oct6100BufferPlayoutAddDef
 
370
UINT32 Oct6100BufferPlayoutAddDef(
 
371
                                tPOCT6100_BUFFER_PLAYOUT_ADD                    f_pBufferPlayoutAdd )
 
372
{
 
373
        f_pBufferPlayoutAdd->ulChannelHndl = cOCT6100_INVALID_HANDLE;
 
374
        f_pBufferPlayoutAdd->ulBufferIndex = cOCT6100_INVALID_VALUE;
 
375
 
 
376
        f_pBufferPlayoutAdd->ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT;
 
377
        f_pBufferPlayoutAdd->ulMixingMode = cOCT6100_MIXING_MINUS_6_DB;
 
378
        f_pBufferPlayoutAdd->lGainDb = 0;
 
379
 
 
380
        f_pBufferPlayoutAdd->fRepeat = FALSE;
 
381
        f_pBufferPlayoutAdd->ulRepeatCount = cOCT6100_REPEAT_INFINITELY;
 
382
 
 
383
        f_pBufferPlayoutAdd->ulDuration = cOCT6100_INVALID_VALUE;
 
384
        
 
385
        f_pBufferPlayoutAdd->ulBufferLength = cOCT6100_AUTO_SELECT;
 
386
 
 
387
        return cOCT6100_ERR_OK;
 
388
}
 
389
#endif
 
390
 
 
391
#if !SKIP_Oct6100BufferPlayoutAdd
 
392
UINT32 Oct6100BufferPlayoutAdd(
 
393
                                tPOCT6100_INSTANCE_API                                  f_pApiInstance,
 
394
                                tPOCT6100_BUFFER_PLAYOUT_ADD                    f_pBufferPlayoutAdd )
 
395
{
 
396
        tOCT6100_SEIZE_SERIALIZE_OBJECT         SeizeSerObj;
 
397
        tOCT6100_RELEASE_SERIALIZE_OBJECT       ReleaseSerObj;
 
398
        UINT32                                                          ulSerRes = cOCT6100_ERR_OK;
 
399
        UINT32                                                          ulFncRes = cOCT6100_ERR_OK;
 
400
 
 
401
        /* Set the process context of the serialize structure. */
 
402
        SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext;
 
403
        ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext;
 
404
 
 
405
        /* Seize all list semaphores needed by this function. */
 
406
        SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
 
407
        SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY;
 
408
        ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj );
 
409
        if ( ulSerRes == cOCT6100_ERR_OK )
 
410
        {
 
411
                /* Call the serialized function. */
 
412
                ulFncRes = Oct6100BufferPlayoutAddSer( f_pApiInstance, f_pBufferPlayoutAdd );
 
413
        }
 
414
        else
 
415
        {
 
416
                return ulSerRes;
 
417
        }
 
418
 
 
419
        /* Release the seized semaphores. */
 
420
        ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
 
421
        ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj );
 
422
 
 
423
        /* If an error occured then return the error code. */
 
424
        if ( ulSerRes != cOCT6100_ERR_OK )
 
425
                return ulSerRes;
 
426
        if ( ulFncRes != cOCT6100_ERR_OK )
 
427
                return ulFncRes;
 
428
 
 
429
        return cOCT6100_ERR_OK;
 
430
}
 
431
#endif
 
432
 
 
433
 
 
434
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
435
 
 
436
Function:               Oct6100BufferPlayoutStart
 
437
 
 
438
Description:    This function enables playout of the specified buffer on the 
 
439
                                requested channel.
 
440
 
 
441
-------------------------------------------------------------------------------
 
442
|       Argument                |       Description
 
443
-------------------------------------------------------------------------------
 
444
f_pApiInstance                  Pointer to API instance. This memory is used to keep the
 
445
                                                present state of the chip and all its resources.
 
446
 
 
447
f_pBufferPlayoutStart   Pointer to buffer playout start structure.
 
448
 
 
449
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
450
#if !SKIP_Oct6100BufferPlayoutStartDef
 
451
UINT32 Oct6100BufferPlayoutStartDef(
 
452
                                tPOCT6100_BUFFER_PLAYOUT_START  f_pBufferPlayoutStart )
 
453
{
 
454
        f_pBufferPlayoutStart->ulChannelHndl = cOCT6100_INVALID_HANDLE;
 
455
        f_pBufferPlayoutStart->ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT;
 
456
        f_pBufferPlayoutStart->fNotifyOnPlayoutStop = FALSE;
 
457
        f_pBufferPlayoutStart->ulUserEventId = cOCT6100_INVALID_VALUE;
 
458
        f_pBufferPlayoutStart->fAllowStartWhileActive = FALSE;
 
459
 
 
460
        return cOCT6100_ERR_OK;
 
461
}
 
462
#endif
 
463
 
 
464
#if !SKIP_Oct6100BufferPlayoutStart
 
465
UINT32 Oct6100BufferPlayoutStart(
 
466
                                tPOCT6100_INSTANCE_API                          f_pApiInstance,
 
467
                                tPOCT6100_BUFFER_PLAYOUT_START          f_pBufferPlayoutStart )
 
468
{
 
469
        tOCT6100_SEIZE_SERIALIZE_OBJECT         SeizeSerObj;
 
470
        tOCT6100_RELEASE_SERIALIZE_OBJECT       ReleaseSerObj;
 
471
        UINT32                                                          ulSerRes = cOCT6100_ERR_OK;
 
472
        UINT32                                                          ulFncRes = cOCT6100_ERR_OK;
 
473
 
 
474
        /* Set the process context of the serialize structure. */
 
475
        SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext;
 
476
        ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext;
 
477
 
 
478
        /* Seize all list semaphores needed by this function. */
 
479
        SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
 
480
        SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY;
 
481
        ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj );
 
482
        if ( ulSerRes == cOCT6100_ERR_OK )
 
483
        {
 
484
                /* Call the serialized function. */
 
485
                ulFncRes = Oct6100BufferPlayoutStartSer( f_pApiInstance, f_pBufferPlayoutStart, cOCT6100_BUFFER_PLAYOUT_EVENT_STOP );
 
486
        }
 
487
        else
 
488
        {
 
489
                return ulSerRes;
 
490
        }
 
491
 
 
492
        /* Release the seized semaphores. */
 
493
        ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
 
494
        ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj );
 
495
 
 
496
        /* If an error occured then return the error code. */
 
497
        if ( ulSerRes != cOCT6100_ERR_OK )
 
498
                return ulSerRes;
 
499
        if ( ulFncRes != cOCT6100_ERR_OK )
 
500
                return ulFncRes;
 
501
 
 
502
        return cOCT6100_ERR_OK;
 
503
}
 
504
#endif
 
505
 
 
506
 
 
507
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
508
 
 
509
Function:               Oct6100BufferPlayoutStop
 
510
 
 
511
Description:    This function disables playout of a buffer on the specified 
 
512
                                channel.
 
513
 
 
514
-------------------------------------------------------------------------------
 
515
|       Argument                |       Description
 
516
-------------------------------------------------------------------------------
 
517
f_pApiInstance                  Pointer to API instance. This memory is used to keep the
 
518
                                                present state of the chip and all its resources.
 
519
 
 
520
f_pBufferPlayoutStop    Pointer to buffer playout stop structure.
 
521
 
 
522
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
523
#if !SKIP_Oct6100BufferPlayoutStopDef
 
524
UINT32 Oct6100BufferPlayoutStopDef(
 
525
                                tPOCT6100_BUFFER_PLAYOUT_STOP   f_pBufferPlayoutStop )
 
526
{
 
527
        f_pBufferPlayoutStop->ulChannelHndl = cOCT6100_INVALID_HANDLE;
 
528
        f_pBufferPlayoutStop->ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT;
 
529
        f_pBufferPlayoutStop->fStopCleanly = TRUE;
 
530
        f_pBufferPlayoutStop->pfAlreadyStopped = NULL;
 
531
        f_pBufferPlayoutStop->pfNotifyOnPlayoutStop = NULL;
 
532
 
 
533
        return cOCT6100_ERR_OK;
 
534
}
 
535
#endif
 
536
 
 
537
#if !SKIP_Oct6100BufferPlayoutStop
 
538
UINT32 Oct6100BufferPlayoutStop(
 
539
                                tPOCT6100_INSTANCE_API                          f_pApiInstance,
 
540
                                tPOCT6100_BUFFER_PLAYOUT_STOP   f_pBufferPlayoutStop )
 
541
{
 
542
        tOCT6100_SEIZE_SERIALIZE_OBJECT         SeizeSerObj;
 
543
        tOCT6100_RELEASE_SERIALIZE_OBJECT       ReleaseSerObj;
 
544
        UINT32                                                          ulSerRes = cOCT6100_ERR_OK;
 
545
        UINT32                                                          ulFncRes = cOCT6100_ERR_OK;
 
546
 
 
547
        /* Set the process context of the serialize structure. */
 
548
        SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext;
 
549
        ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext;
 
550
 
 
551
        /* Seize all list semaphores needed by this function. */
 
552
        SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
 
553
        SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY;
 
554
        ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj );
 
555
        if ( ulSerRes == cOCT6100_ERR_OK )
 
556
        {
 
557
                /* Call the serialized function. */
 
558
                ulFncRes = Oct6100BufferPlayoutStopSer( f_pApiInstance, f_pBufferPlayoutStop );
 
559
        }
 
560
        else
 
561
        {
 
562
                return ulSerRes;
 
563
        }
 
564
 
 
565
        /* Release the seized semaphores. */
 
566
        ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
 
567
        ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj );
 
568
 
 
569
        /* If an error occured then return the error code. */
 
570
        if ( ulSerRes != cOCT6100_ERR_OK )
 
571
                return ulSerRes;
 
572
        if ( ulFncRes != cOCT6100_ERR_OK )
 
573
                return ulFncRes;
 
574
 
 
575
        return cOCT6100_ERR_OK;
 
576
}
 
577
#endif
 
578
 
 
579
 
 
580
/****************************  PRIVATE FUNCTIONS  ****************************/
 
581
 
 
582
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
583
 
 
584
Function:               Oct6100ApiGetPlayoutBufferSwSizes
 
585
 
 
586
Description:    Gets the sizes of all portions of the API instance pertinent
 
587
                                to the management of playout buffers.
 
588
 
 
589
-------------------------------------------------------------------------------
 
590
|       Argument                |       Description
 
591
-------------------------------------------------------------------------------
 
592
f_pOpenChip                             Pointer to chip configuration struct.
 
593
f_pInstSizes                    Pointer to struct containing instance sizes.
 
594
 
 
595
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
596
#if !SKIP_Oct6100ApiGetPlayoutBufferSwSizes
 
597
UINT32 Oct6100ApiGetPlayoutBufferSwSizes(
 
598
                                IN              tPOCT6100_CHIP_OPEN                             f_pOpenChip,
 
599
                                OUT             tPOCT6100_API_INSTANCE_SIZES    f_pInstSizes )
 
600
{
 
601
        UINT32  ulTempVar;
 
602
        UINT32  ulResult;
 
603
 
 
604
        /* Calculate memory needed for playout buffer list. */
 
605
        f_pInstSizes->ulPlayoutBufList = f_pOpenChip->ulMaxPlayoutBuffers * sizeof( tOCT6100_API_BUFFER );
 
606
 
 
607
        f_pInstSizes->ulPlayoutBufMemoryNodeList = 0;
 
608
        
 
609
        /* Calculate memory needed for playout buffer allocation software. */
 
610
        if ( f_pOpenChip->ulMaxPlayoutBuffers > 0 )
 
611
        {
 
612
                ulResult = OctapiLlmAllocGetSize( f_pOpenChip->ulMaxPlayoutBuffers, &f_pInstSizes->ulPlayoutBufAlloc );
 
613
                if ( ulResult != cOCT6100_ERR_OK )
 
614
                        return cOCT6100_ERR_FATAL_3C;
 
615
                
 
616
                f_pInstSizes->ulPlayoutBufMemoryNodeList = 2 * f_pOpenChip->ulMaxPlayoutBuffers * sizeof( tOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE );
 
617
        }
 
618
        else
 
619
        {
 
620
                f_pInstSizes->ulPlayoutBufAlloc  = 0;
 
621
        }
 
622
 
 
623
        /* Calculate memory needed for list and allocation software serialization. */
 
624
        mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulPlayoutBufList, ulTempVar )
 
625
        mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulPlayoutBufAlloc, ulTempVar )
 
626
        mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulPlayoutBufMemoryNodeList, ulTempVar )
 
627
 
 
628
        return cOCT6100_ERR_OK;
 
629
}
 
630
#endif
 
631
 
 
632
 
 
633
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
634
 
 
635
Function:               Oct6100ApiPlayoutBufferSwInit
 
636
 
 
637
Description:    Initializes all elements of the instance structure associated
 
638
                                to playout buffers.
 
639
 
 
640
-------------------------------------------------------------------------------
 
641
|       Argument                |       Description
 
642
-------------------------------------------------------------------------------
 
643
f_pApiInstance                  Pointer to API instance. This memory is used to keep
 
644
                                                the present state of the chip and all its resources.
 
645
 
 
646
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
647
#if !SKIP_Oct6100ApiPlayoutBufferSwInit
 
648
UINT32 Oct6100ApiPlayoutBufferSwInit(
 
649
                                IN OUT  tPOCT6100_INSTANCE_API                  f_pApiInstance )
 
650
{
 
651
        tPOCT6100_SHARED_INFO                   pSharedInfo;
 
652
        tPOCT6100_API_BUFFER                    pBufferList;
 
653
        PVOID   pBufferPlayoutAlloc;
 
654
        UINT32  ulMaxBufferPlayout;
 
655
        UINT32  ulResult, i;
 
656
 
 
657
        /* Get local pointer to shared portion of instance. */
 
658
        pSharedInfo = f_pApiInstance->pSharedInfo;
 
659
 
 
660
        /* Get the maximum number of buffer playout. */
 
661
        ulMaxBufferPlayout = pSharedInfo->ChipConfig.usMaxPlayoutBuffers;
 
662
 
 
663
        /* Set all entries in the buffer playout list to unused. */
 
664
        mOCT6100_GET_BUFFER_LIST_PNT( pSharedInfo, pBufferList )
 
665
 
 
666
        for ( i = 0; i < ulMaxBufferPlayout; i++ )
 
667
        {
 
668
                pBufferList[ i ].fReserved = FALSE;
 
669
                pBufferList[ i ].ulBufferSize = 0;
 
670
                pBufferList[ i ].ulBufferBase = cOCT6100_INVALID_VALUE;
 
671
                pBufferList[ i ].usDependencyCnt = 0;
 
672
                pBufferList[ i ].byBufferPcmLaw = cOCT6100_PCM_U_LAW;
 
673
                
 
674
        }
 
675
 
 
676
        /* Initialize the buffer playout allocation software to "all free". */
 
677
        if ( ulMaxBufferPlayout > 0 )
 
678
        {
 
679
                mOCT6100_GET_BUFFER_ALLOC_PNT( pSharedInfo, pBufferPlayoutAlloc )
 
680
                
 
681
                ulResult = OctapiLlmAllocInit( &pBufferPlayoutAlloc, ulMaxBufferPlayout );
 
682
                if ( ulResult != cOCT6100_ERR_OK )
 
683
                        return cOCT6100_ERR_FATAL_3D;
 
684
        }
 
685
 
 
686
        /* Initialize the amount of free memory used by playout. */
 
687
        f_pApiInstance->pSharedInfo->ChipStats.ulPlayoutMemUsed = 0;
 
688
 
 
689
        return cOCT6100_ERR_OK;
 
690
}
 
691
#endif
 
692
 
 
693
 
 
694
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
695
 
 
696
Function:               Oct6100BufferLoadSer
 
697
 
 
698
Description:    Loads a buffer in external memory.
 
699
 
 
700
-------------------------------------------------------------------------------
 
701
|       Argument                |       Description
 
702
-------------------------------------------------------------------------------
 
703
f_pApiInstance                  Pointer to API instance. This memory is used to keep the
 
704
                                                present state of the chip and all its resources.
 
705
 
 
706
f_pBufferLoad                   Pointer to buffer configuration structure. The handle
 
707
                                                identifying the buffer in all future function calls is
 
708
                                                returned in this structure.
 
709
                                                
 
710
f_fReserveListStruct    Flag indicating if a list structure should be reserved
 
711
                                                or if the structure has been reserved before.  If this
 
712
                                                is set, the f_ulBufIndex variable must also be set.
 
713
 
 
714
f_ulBufIndex                    If the f_fReserveListStruct flag is set, this index
 
715
                                                will identify the buffer playout list structure
 
716
                                                that must be used to load the specified buffer.
 
717
 
 
718
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
719
#if !SKIP_Oct6100BufferLoadSer
 
720
UINT32 Oct6100BufferLoadSer(
 
721
                                IN OUT  tPOCT6100_INSTANCE_API          f_pApiInstance,
 
722
                                IN OUT  tPOCT6100_BUFFER_LOAD           f_pBufferLoad,
 
723
                                IN              BOOL                                            f_fReserveListStruct, 
 
724
                                IN              UINT32                                          f_ulBufIndex )
 
725
{
 
726
        UINT32  ulBufferIndex;
 
727
        UINT32  ulBufferBase;
 
728
        UINT32  ulResult;
 
729
 
 
730
        /* Check the user's configuration of the buffer for errors. */
 
731
        ulResult = Oct6100ApiCheckBufferParams( f_pApiInstance, f_pBufferLoad, TRUE );
 
732
        if ( ulResult != cOCT6100_ERR_OK )
 
733
                return ulResult;
 
734
 
 
735
        /* Reserve all resources needed by the buffer. */
 
736
        ulResult = Oct6100ApiReserveBufferResources( f_pApiInstance, f_pBufferLoad, f_fReserveListStruct, f_ulBufIndex, &ulBufferIndex, &ulBufferBase );
 
737
        if ( ulResult != cOCT6100_ERR_OK )
 
738
                return ulResult;
 
739
        
 
740
        /* Write the buffer in external memory. */
 
741
        ulResult = Oct6100ApiWriteBufferInMemory( f_pApiInstance, ulBufferBase, f_pBufferLoad->ulBufferSize, f_pBufferLoad->pbyBufferPattern );
 
742
        if ( ulResult != cOCT6100_ERR_OK )
 
743
                return ulResult;
 
744
 
 
745
        /* Update the new buffer's entry in the buffer list. */
 
746
        ulResult = Oct6100ApiUpdateBufferEntry( f_pApiInstance, f_pBufferLoad, ulBufferIndex, ulBufferBase );
 
747
        if ( ulResult != cOCT6100_ERR_OK )
 
748
                return ulResult;
 
749
 
 
750
        return cOCT6100_ERR_OK;
 
751
}
 
752
#endif
 
753
 
 
754
 
 
755
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
756
 
 
757
Function:               Oct6100BufferLoadBlockInitSer
 
758
 
 
759
Description:    Reserve resources for loading a buffer into external memory.
 
760
 
 
761
-------------------------------------------------------------------------------
 
762
|       Argument                |       Description
 
763
-------------------------------------------------------------------------------
 
764
f_pApiInstance                  Pointer to API instance. This memory is used to keep 
 
765
                                                the present state of the chip and all its resources.
 
766
 
 
767
f_pBufferLoadBlockInit  Pointer to buffer configuration structure. The 
 
768
                                                handle identifying the buffer in all future 
 
769
                                                function calls is returned in this structure.
 
770
 
 
771
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
772
#if !SKIP_Oct6100BufferLoadBlockInitSer
 
773
UINT32 Oct6100BufferLoadBlockInitSer(
 
774
                                IN OUT  tPOCT6100_INSTANCE_API                          f_pApiInstance,
 
775
                                IN OUT  tPOCT6100_BUFFER_LOAD_BLOCK_INIT        f_pBufferLoadBlockInit )
 
776
{
 
777
        UINT32                                  ulBufferIndex;
 
778
        UINT32                                  ulBufferBase;
 
779
        UINT32                                  ulResult;
 
780
        tOCT6100_BUFFER_LOAD    BufferLoad;
 
781
 
 
782
        Oct6100BufferPlayoutLoadDef( &BufferLoad );
 
783
 
 
784
        /* Not to replicate the code, we use the BufferLoad functions directly. */
 
785
        BufferLoad.pulBufferIndex                       = f_pBufferLoadBlockInit->pulBufferIndex;
 
786
        BufferLoad.pulPlayoutFreeMemSize        = f_pBufferLoadBlockInit->pulPlayoutFreeMemSize;
 
787
        BufferLoad.ulBufferPcmLaw                       = f_pBufferLoadBlockInit->ulBufferPcmLaw;
 
788
        BufferLoad.ulBufferSize                         = f_pBufferLoadBlockInit->ulBufferSize;
 
789
        BufferLoad.pbyBufferPattern                     = NULL;  /* Must not check this for now */
 
790
 
 
791
        /* Check the user's configuration of the buffer for errors, but do */
 
792
        /* not check if the buffer pointer is NULL.  It is NULL for sure! */
 
793
        ulResult = Oct6100ApiCheckBufferParams( f_pApiInstance, &BufferLoad, FALSE );
 
794
        if ( ulResult != cOCT6100_ERR_OK )
 
795
                return ulResult;
 
796
 
 
797
        /* Reserve all resources needed by the buffer. */
 
798
        ulResult = Oct6100ApiReserveBufferResources( f_pApiInstance, &BufferLoad, TRUE, cOCT6100_INVALID_INDEX, &ulBufferIndex, &ulBufferBase );
 
799
        if ( ulResult != cOCT6100_ERR_OK )
 
800
                return ulResult;
 
801
 
 
802
        /* Update the new buffer's entry in the buffer list. */
 
803
        ulResult = Oct6100ApiUpdateBufferEntry( f_pApiInstance, &BufferLoad, ulBufferIndex, ulBufferBase );
 
804
        if ( ulResult != cOCT6100_ERR_OK )
 
805
                return ulResult;
 
806
 
 
807
        return cOCT6100_ERR_OK;
 
808
}
 
809
#endif
 
810
 
 
811
 
 
812
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
813
 
 
814
Function:               Oct6100BufferLoadBlockSer
 
815
 
 
816
Description:    Loads a buffer in external memory using blocks.
 
817
 
 
818
-------------------------------------------------------------------------------
 
819
|       Argument                |       Description
 
820
-------------------------------------------------------------------------------
 
821
f_pApiInstance                  Pointer to API instance. This memory is used to keep 
 
822
                                                the present state of the chip and all its resources.
 
823
 
 
824
f_pBufferLoadBlock              Pointer to buffer block to be loaded into external 
 
825
                                                memory descriptor. 
 
826
 
 
827
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
828
#if !SKIP_Oct6100BufferLoadBlockSer
 
829
UINT32 Oct6100BufferLoadBlockSer(
 
830
                                IN OUT  tPOCT6100_INSTANCE_API                          f_pApiInstance,
 
831
                                IN OUT  tPOCT6100_BUFFER_LOAD_BLOCK                     f_pBufferLoadBlock )
 
832
{
 
833
        UINT32  ulBufferBase;
 
834
        UINT32  ulResult;
 
835
 
 
836
        /* Check the user's configuration for errors. */
 
837
        ulResult = Oct6100ApiCheckBufferLoadBlockParams( f_pApiInstance, f_pBufferLoadBlock, &ulBufferBase );
 
838
        if ( ulResult != cOCT6100_ERR_OK )
 
839
                return ulResult;
 
840
 
 
841
        /* Write the buffer in external memory at the appropriate offset - must do some pointer arithmetic. */
 
842
        ulResult = Oct6100ApiWriteBufferInMemory( f_pApiInstance, ulBufferBase + f_pBufferLoadBlock->ulBlockOffset, 
 
843
                                        f_pBufferLoadBlock->ulBlockLength, f_pBufferLoadBlock->pbyBufferPattern + f_pBufferLoadBlock->ulBlockOffset );
 
844
        if ( ulResult != cOCT6100_ERR_OK )
 
845
                return ulResult;
 
846
 
 
847
        return cOCT6100_ERR_OK;
 
848
}
 
849
#endif
 
850
 
 
851
 
 
852
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
853
 
 
854
Function:               Oct6100ApiCheckBufferParams
 
855
 
 
856
Description:    Checks the user's buffer playout load configuration for errors.
 
857
 
 
858
-------------------------------------------------------------------------------
 
859
|       Argument                |       Description
 
860
-------------------------------------------------------------------------------
 
861
f_pApiInstance                  Pointer to API instance. This memory is used to keep the
 
862
                                                present state of the chip and all its resources.
 
863
 
 
864
f_pBufferLoad                   Pointer to buffer configuration structure.
 
865
f_fCheckBufferPtr               Check if the buffer pointer is NULL or not.
 
866
 
 
867
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
868
#if !SKIP_Oct6100ApiCheckBufferParams
 
869
UINT32 Oct6100ApiCheckBufferParams(
 
870
                                IN OUT  tPOCT6100_INSTANCE_API                  f_pApiInstance,
 
871
                                IN OUT  tPOCT6100_BUFFER_LOAD                   f_pBufferLoad,
 
872
                                IN              BOOL                                                    f_fCheckBufferPtr )
 
873
{
 
874
        /* Check for errors. */
 
875
        if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxPlayoutBuffers == 0 )
 
876
                return cOCT6100_ERR_BUFFER_PLAYOUT_DISABLED;
 
877
 
 
878
        if ( f_pApiInstance->pSharedInfo->ImageInfo.fBufferPlayout == FALSE )
 
879
                return cOCT6100_ERR_NOT_SUPPORTED_BUFFER_PLAYOUT;
 
880
 
 
881
        if ( f_pBufferLoad->pulBufferIndex == NULL )
 
882
                return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_INDEX;
 
883
 
 
884
        if( f_fCheckBufferPtr )
 
885
        {
 
886
                if ( f_pBufferLoad->pbyBufferPattern == NULL )
 
887
                        return cOCT6100_ERR_BUFFER_PLAYOUT_PATTERN;
 
888
        }
 
889
 
 
890
        if ( f_pBufferLoad->ulBufferSize < cOCT6100_MINIMUM_BUFFER_SIZE )
 
891
                return cOCT6100_ERR_BUFFER_PLAYOUT_TOO_SMALL;
 
892
 
 
893
        if ( ( f_pBufferLoad->ulBufferSize % cOCT6100_BUFFER_SIZE_GRANULARITY ) != 0 )
 
894
                return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_SIZE;
 
895
 
 
896
        if ( f_pBufferLoad->ulBufferPcmLaw != cOCT6100_PCM_U_LAW && 
 
897
                 f_pBufferLoad->ulBufferPcmLaw != cOCT6100_PCM_A_LAW )
 
898
                return cOCT6100_ERR_BUFFER_PLAYOUT_PCM_LAW;
 
899
 
 
900
        return cOCT6100_ERR_OK;
 
901
}
 
902
#endif
 
903
 
 
904
 
 
905
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
906
 
 
907
Function:               Oct6100ApiCheckBufferLoadBlockParams
 
908
 
 
909
Description:    Checks the user's buffer playout load block configuration for 
 
910
                                errors.
 
911
 
 
912
-------------------------------------------------------------------------------
 
913
|       Argument                |       Description
 
914
-------------------------------------------------------------------------------
 
915
f_pApiInstance                  Pointer to API instance. This memory is used to keep the
 
916
                                                present state of the chip and all its resources.
 
917
 
 
918
f_pBufferLoadBlock              Pointer to buffer block descriptor.
 
919
f_pulBufferBase                 Pointer to the base address of the buffer in external 
 
920
                                                memory.
 
921
 
 
922
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
923
#if !SKIP_Oct6100ApiCheckBufferLoadBlockParams
 
924
UINT32 Oct6100ApiCheckBufferLoadBlockParams(
 
925
                                IN OUT  tPOCT6100_INSTANCE_API                  f_pApiInstance,
 
926
                                IN              tPOCT6100_BUFFER_LOAD_BLOCK             f_pBufferLoadBlock,
 
927
                                OUT             PUINT32                                                 f_pulBufferBase )
 
928
{
 
929
        /* Check for errors. */
 
930
        tPOCT6100_API_BUFFER    pBufEntry;
 
931
 
 
932
        if ( f_pBufferLoadBlock->ulBufferIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxPlayoutBuffers )
 
933
                return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_INDEX;
 
934
 
 
935
        mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBufEntry, f_pBufferLoadBlock->ulBufferIndex )
 
936
 
 
937
        if ( pBufEntry->fReserved != TRUE )
 
938
                return cOCT6100_ERR_BUFFER_PLAYOUT_NOT_OPEN;
 
939
 
 
940
        if ( ( f_pBufferLoadBlock->ulBlockLength % 2 ) != 0 )
 
941
                return cOCT6100_ERR_BUFFER_PLAYOUT_BLOCK_LENGTH_INVALID;
 
942
 
 
943
        if ( ( f_pBufferLoadBlock->ulBlockOffset % 2 ) != 0 )
 
944
                return cOCT6100_ERR_BUFFER_PLAYOUT_BLOCK_OFFSET_INVALID;
 
945
 
 
946
        if ( f_pBufferLoadBlock->pbyBufferPattern == NULL )
 
947
                return cOCT6100_ERR_BUFFER_PLAYOUT_PATTERN;
 
948
 
 
949
        /* Check boundaries */
 
950
        if ( ( f_pBufferLoadBlock->ulBlockLength + f_pBufferLoadBlock->ulBlockOffset ) > pBufEntry->ulBufferSize )
 
951
                return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_SIZE;
 
952
 
 
953
        *f_pulBufferBase = pBufEntry->ulBufferBase;
 
954
 
 
955
        return cOCT6100_ERR_OK;
 
956
}
 
957
#endif
 
958
 
 
959
 
 
960
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
961
 
 
962
Function:               Oct6100ApiReserveBufferResources
 
963
 
 
964
Description:    Reserves all resources needed for the new buffer.
 
965
 
 
966
-------------------------------------------------------------------------------
 
967
|       Argument                |       Description
 
968
-------------------------------------------------------------------------------
 
969
f_pApiInstance                  Pointer to API instance. This memory is used to keep the
 
970
                                                present state of the chip and all its resources.
 
971
        
 
972
f_pBufferLoad                   Pointer to buffer configuration structure.
 
973
 
 
974
f_fReserveListStruct    Flag indicating if a list structure should be reserved
 
975
                                                or if the structure has been reserved before.
 
976
 
 
977
f_ulBufIndex                    If the f_fReserveListStruct flag is set, this index
 
978
                                                will identifying the buffer playout list structure
 
979
                                                that must be used to load the specified buffer.
 
980
 
 
981
f_pulBufferIndex                Allocated entry in buffer playout list.
 
982
        
 
983
f_pulBufferBase                 Allocated external memory block for the buffer.
 
984
 
 
985
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
986
#if !SKIP_Oct6100ApiReserveBufferResources
 
987
UINT32 Oct6100ApiReserveBufferResources(
 
988
                                IN OUT  tPOCT6100_INSTANCE_API                  f_pApiInstance,
 
989
                                IN              tPOCT6100_BUFFER_LOAD                   f_pBufferLoad,
 
990
                                IN              BOOL                                                    f_fReserveListStruct,
 
991
                                IN              UINT32                                                  f_ulBufIndex,
 
992
                                OUT             PUINT32                                                 f_pulBufferIndex,
 
993
                                OUT             PUINT32                                                 f_pulBufferBase )
 
994
{
 
995
        tPOCT6100_SHARED_INFO   pSharedInfo;
 
996
        UINT32  ulResult = cOCT6100_ERR_OK;
 
997
        UINT32  ulTempVar;
 
998
 
 
999
        /* Obtain local pointer to shared portion of instance. */
 
1000
        pSharedInfo = f_pApiInstance->pSharedInfo;
 
1001
        
 
1002
        /* Reserve an entry in the buffer list. */
 
1003
        if ( f_fReserveListStruct == TRUE )
 
1004
        {
 
1005
                ulResult = Oct6100ApiReserveBufPlayoutListEntry( f_pApiInstance, f_pulBufferIndex );
 
1006
        }
 
1007
        else
 
1008
        {
 
1009
                *f_pulBufferIndex = f_ulBufIndex;
 
1010
        }
 
1011
        if ( ulResult == cOCT6100_ERR_OK )
 
1012
        {
 
1013
                /* Find a free block to store the buffer. */
 
1014
                ulResult = Oct6100ApiReserveBufferPlayoutMemory( f_pApiInstance, f_pBufferLoad->ulBufferSize, f_pulBufferBase );
 
1015
                if ( ulResult != cOCT6100_ERR_OK )
 
1016
                {
 
1017
                        /* Release the list entry. */
 
1018
                        if ( f_fReserveListStruct == TRUE )
 
1019
                        {
 
1020
                                ulTempVar = Oct6100ApiReleaseBufPlayoutListEntry( f_pApiInstance, *f_pulBufferIndex );
 
1021
                                if ( ulTempVar != cOCT6100_ERR_OK )
 
1022
                                        return ulTempVar;
 
1023
                        }
 
1024
                }
 
1025
        }
 
1026
 
 
1027
        return ulResult;
 
1028
}
 
1029
#endif
 
1030
 
 
1031
 
 
1032
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
1033
 
 
1034
Function:               Oct6100ApiWriteBufferInMemory
 
1035
 
 
1036
Description:    Writes the buffer in external memory.
 
1037
 
 
1038
-------------------------------------------------------------------------------
 
1039
|       Argument                |       Description
 
1040
-------------------------------------------------------------------------------
 
1041
f_pApiInstance                  Pointer to API instance. This memory is used to keep
 
1042
                                                the present state of the chip and all its resources.
 
1043
 
 
1044
f_ulBufferBase                  Allocated external memory address for the buffer.
 
1045
 
 
1046
f_ulBufferLength                Length in bytes of the buffer to be copied in memory.
 
1047
 
 
1048
f_pbyBuffer                             Address where the buffer should be copied from.
 
1049
 
 
1050
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
1051
#if !SKIP_Oct6100ApiWriteBufferInMemory
 
1052
UINT32 Oct6100ApiWriteBufferInMemory( 
 
1053
                                IN OUT  tPOCT6100_INSTANCE_API  f_pApiInstance,
 
1054
                                IN              UINT32                                  f_ulBufferBase,
 
1055
                                IN              UINT32                                  f_ulBufferLength,
 
1056
                                IN              PUINT8                                  f_pbyBuffer )
 
1057
{
 
1058
        tPOCT6100_SHARED_INFO           pSharedInfo;
 
1059
        tOCT6100_WRITE_BURST_PARAMS     BurstParams;
 
1060
        tOCT6100_WRITE_PARAMS           WriteParams;
 
1061
        UINT32                                          ulResult;
 
1062
        UINT32                                          ulNumWrites;
 
1063
        PUINT16                                         pusSuperArray;
 
1064
        PUINT8                                          pbyPlayoutBuffer;
 
1065
        UINT32                                          ulByteCount = 0;
 
1066
        UINT32                                          i;
 
1067
 
 
1068
        /* Get local pointer to shared portion of instance. */
 
1069
        pSharedInfo = f_pApiInstance->pSharedInfo;
 
1070
 
 
1071
        /* Set the process context and user chip ID parameters once and for all. */
 
1072
        BurstParams.pProcessContext = f_pApiInstance->pProcessContext;
 
1073
 
 
1074
        BurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
 
1075
 
 
1076
        WriteParams.pProcessContext = f_pApiInstance->pProcessContext;
 
1077
 
 
1078
        WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
 
1079
 
 
1080
        /* Write the buffer in external memory. */
 
1081
        ulNumWrites = f_ulBufferLength / 2;
 
1082
 
 
1083
        BurstParams.ulWriteAddress = f_ulBufferBase;
 
1084
        BurstParams.pusWriteData = pSharedInfo->MiscVars.ausSuperArray;
 
1085
 
 
1086
        pusSuperArray = pSharedInfo->MiscVars.ausSuperArray;
 
1087
        pbyPlayoutBuffer = f_pbyBuffer;
 
1088
        
 
1089
        /* Check if we can maximize the bandwidth through the CPU port. */
 
1090
        if ( f_pApiInstance->pSharedInfo->ChipStats.usNumberChannels == 0 )
 
1091
        {
 
1092
                WriteParams.ulWriteAddress = 0x234;
 
1093
                WriteParams.usWriteData = 0x08ff;
 
1094
                mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult );
 
1095
                if ( ulResult != cOCT6100_ERR_OK  )
 
1096
                        return ulResult;
 
1097
        }
 
1098
 
 
1099
        while ( ulNumWrites != 0 )
 
1100
        {
 
1101
                if ( ulNumWrites >= pSharedInfo->ChipConfig.usMaxRwAccesses )
 
1102
                        BurstParams.ulWriteLength = pSharedInfo->ChipConfig.usMaxRwAccesses;
 
1103
                else
 
1104
                        BurstParams.ulWriteLength = ulNumWrites;
 
1105
 
 
1106
                for ( i = 0; i < BurstParams.ulWriteLength; i++ )
 
1107
                {
 
1108
                        pusSuperArray[ i ]  = ( UINT16 )(( pbyPlayoutBuffer [ ulByteCount++ ]) << 8);
 
1109
                        pusSuperArray[ i ] |= ( UINT16 )pbyPlayoutBuffer [ ulByteCount++ ];
 
1110
                }
 
1111
 
 
1112
                mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult )
 
1113
                if ( ulResult != cOCT6100_ERR_OK )
 
1114
                        return ulResult;
 
1115
 
 
1116
                BurstParams.ulWriteAddress += 2 * BurstParams.ulWriteLength;
 
1117
                ulNumWrites -= BurstParams.ulWriteLength;
 
1118
 
 
1119
        }
 
1120
 
 
1121
        /* Make sure we revert back the changes made to the CPU bandwidth register. */
 
1122
        if ( f_pApiInstance->pSharedInfo->ChipStats.usNumberChannels == 0 )
 
1123
        {
 
1124
                WriteParams.ulWriteAddress = 0x234;
 
1125
                WriteParams.usWriteData = 0x0804;
 
1126
                mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult );
 
1127
                if ( ulResult != cOCT6100_ERR_OK )
 
1128
                        return ulResult;
 
1129
        }
 
1130
 
 
1131
        return cOCT6100_ERR_OK;
 
1132
}
 
1133
#endif
 
1134
        
 
1135
 
 
1136
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
1137
 
 
1138
Function:               Oct6100ApiUpdateBufferEntry
 
1139
 
 
1140
Description:    Updates the new buffer's entry in the buffer playout list.
 
1141
 
 
1142
-------------------------------------------------------------------------------
 
1143
|       Argument                |       Description
 
1144
-------------------------------------------------------------------------------
 
1145
f_pApiInstance                  Pointer to API instance. This memory is used to keep
 
1146
                                                the present state of the chip and all its resources.
 
1147
 
 
1148
f_pBufferLoad                   Pointer to buffer configuration structure.
 
1149
f_ulBufferIndex                 Allocated entry in buffer playout list.
 
1150
f_ulBufferBase                  Allocated external memory block for the buffer.
 
1151
 
 
1152
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
1153
#if !SKIP_Oct6100ApiUpdateBufferEntry
 
1154
UINT32 Oct6100ApiUpdateBufferEntry(
 
1155
                                IN OUT  tPOCT6100_INSTANCE_API                  f_pApiInstance,
 
1156
                                IN OUT  tPOCT6100_BUFFER_LOAD                   f_pBufferLoad,
 
1157
                                IN              UINT32                                                  f_ulBufferIndex,
 
1158
                                IN              UINT32                                                  f_ulBufferBase )
 
1159
{
 
1160
        tPOCT6100_API_BUFFER    pBufEntry;
 
1161
        UINT32                                  ulBufferSize = f_pBufferLoad->ulBufferSize;
 
1162
 
 
1163
        /* Obtain a pointer to the new buffer's list entry. */
 
1164
        mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBufEntry, f_ulBufferIndex )
 
1165
 
 
1166
        /* Copy the buffer's configuration and allocated resources. */
 
1167
        pBufEntry->ulBufferSize = f_pBufferLoad->ulBufferSize;
 
1168
        pBufEntry->byBufferPcmLaw = (UINT8)( f_pBufferLoad->ulBufferPcmLaw & 0xFF );
 
1169
        pBufEntry->ulBufferBase = f_ulBufferBase;
 
1170
        
 
1171
        /* Update the entries flags. */
 
1172
        pBufEntry->usDependencyCnt = 0;
 
1173
 
 
1174
        /* Mark the buffer as opened. */
 
1175
        pBufEntry->fReserved = TRUE;
 
1176
 
 
1177
        /* Increment the number of buffer loaded into the chip.*/
 
1178
        f_pApiInstance->pSharedInfo->ChipStats.usNumberPlayoutBuffers++;
 
1179
        
 
1180
        /* Refresh the amount of memory used by buffer playout. */
 
1181
 
 
1182
        /* Reserved size is divisible by 64. */
 
1183
        if ( ulBufferSize % 64 )
 
1184
                ulBufferSize = ulBufferSize + ( 64 - ( ulBufferSize % 64 ) );
 
1185
        f_pApiInstance->pSharedInfo->ChipStats.ulPlayoutMemUsed += ulBufferSize;
 
1186
        
 
1187
        /* Return the buffer index to the user. */
 
1188
        *f_pBufferLoad->pulBufferIndex = f_ulBufferIndex;
 
1189
 
 
1190
        /* Return the amount of free memory left in the chip. */
 
1191
        /* Note that this value does not give the "fragmentation" state of the available memory. */
 
1192
        /* This value only gives the amount of free memory */
 
1193
        if( f_pBufferLoad->pulPlayoutFreeMemSize )
 
1194
                *f_pBufferLoad->pulPlayoutFreeMemSize = ( f_pApiInstance->pSharedInfo->MiscVars.ulTotalMemSize - ( f_pApiInstance->pSharedInfo->MemoryMap.ulFreeMemBaseAddress - cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) ) - ( f_pApiInstance->pSharedInfo->ChipStats.ulPlayoutMemUsed );
 
1195
 
 
1196
        return cOCT6100_ERR_OK;
 
1197
}
 
1198
#endif
 
1199
 
 
1200
 
 
1201
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
1202
 
 
1203
Function:               Oct6100BufferUnloadSer
 
1204
 
 
1205
Description:    Unloads a buffer from external memory.
 
1206
 
 
1207
-------------------------------------------------------------------------------
 
1208
|       Argument                |       Description
 
1209
-------------------------------------------------------------------------------
 
1210
f_pApiInstance                  Pointer to API instance. This memory is used to keep the
 
1211
                                                present state of the chip and all its resources.
 
1212
 
 
1213
f_pBufferUnload                 Pointer to buffer unload structure.
 
1214
f_fReleaseListStruct    Whether to release the buffer playout list structure
 
1215
                                                or not.
 
1216
 
 
1217
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
1218
#if !SKIP_Oct6100BufferUnloadSer
 
1219
UINT32 Oct6100BufferUnloadSer(
 
1220
                                IN OUT  tPOCT6100_INSTANCE_API                          f_pApiInstance,
 
1221
                                IN OUT  tPOCT6100_BUFFER_UNLOAD                         f_pBufferUnload,
 
1222
                                IN              BOOL                                                            f_fReleaseListStruct )
 
1223
{
 
1224
        UINT32  ulBufferIndex;
 
1225
        UINT32  ulBufferBase;
 
1226
        UINT32  ulResult;
 
1227
 
 
1228
        /* Verify that all the parameters given match the state of the API. */
 
1229
        ulResult = Oct6100ApiAssertBufferParams( f_pApiInstance, f_pBufferUnload, &ulBufferIndex, &ulBufferBase );
 
1230
        if ( ulResult != cOCT6100_ERR_OK )
 
1231
                return ulResult;
 
1232
 
 
1233
        /* Release all resources associated to the unloaded buffer. */
 
1234
        ulResult = Oct6100ApiReleaseBufferResources( f_pApiInstance, ulBufferIndex, ulBufferBase, f_fReleaseListStruct );
 
1235
        if ( ulResult != cOCT6100_ERR_OK )
 
1236
                return ulResult;
 
1237
 
 
1238
        return cOCT6100_ERR_OK;
 
1239
}
 
1240
#endif
 
1241
 
 
1242
 
 
1243
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
1244
 
 
1245
Function:               Oct6100ApiAssertBufferParams
 
1246
 
 
1247
Description:    Checks the buffer playout unload configuration for errors.
 
1248
 
 
1249
-------------------------------------------------------------------------------
 
1250
|       Argument                |       Description
 
1251
-------------------------------------------------------------------------------
 
1252
f_pApiInstance                  Pointer to API instance. This memory is used to keep the
 
1253
                                                present state of the chip and all its resources.
 
1254
 
 
1255
f_pBufferUnload                 Pointer to buffer unload structure.
 
1256
f_pulBufferIndex                Pointer to the index of the buffer in the API's buffers list.
 
1257
f_pulBufferBase                 Pointer to the base address of the buffer in external memory.
 
1258
 
 
1259
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
1260
#if !SKIP_Oct6100ApiAssertBufferParams
 
1261
UINT32 Oct6100ApiAssertBufferParams(
 
1262
                                IN OUT  tPOCT6100_INSTANCE_API                          f_pApiInstance,
 
1263
                                IN              tPOCT6100_BUFFER_UNLOAD                         f_pBufferUnload,
 
1264
                                OUT             PUINT32                                                         f_pulBufferIndex,
 
1265
                                OUT             PUINT32                                                         f_pulBufferBase )
 
1266
{
 
1267
        tPOCT6100_API_BUFFER    pBufEntry;
 
1268
 
 
1269
        *f_pulBufferIndex = f_pBufferUnload->ulBufferIndex;
 
1270
 
 
1271
        if ( *f_pulBufferIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxPlayoutBuffers )
 
1272
                return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_INDEX;
 
1273
 
 
1274
        mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBufEntry, *f_pulBufferIndex )
 
1275
 
 
1276
        /* Check for errors. */
 
1277
        if ( pBufEntry->fReserved != TRUE )
 
1278
                return cOCT6100_ERR_BUFFER_PLAYOUT_NOT_OPEN;
 
1279
        if ( pBufEntry->usDependencyCnt != 0 )
 
1280
                return cOCT6100_ERR_BUFFER_PLAYOUT_ACTIVE_DEPENDENCIES;
 
1281
        
 
1282
        /* Return all info needed to invalidate buffer. */
 
1283
        *f_pulBufferBase = pBufEntry->ulBufferBase;
 
1284
 
 
1285
        return cOCT6100_ERR_OK;
 
1286
}
 
1287
#endif
 
1288
 
 
1289
 
 
1290
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
1291
 
 
1292
Function:               Oct6100ApiReleaseBufferResources
 
1293
 
 
1294
Description:    Release resources needed by the buffer.
 
1295
 
 
1296
-------------------------------------------------------------------------------
 
1297
|       Argument                |       Description
 
1298
-------------------------------------------------------------------------------
 
1299
f_pApiInstance                  Pointer to API instance. This memory is used to keep the
 
1300
                                                present state of the chip and all its resources.
 
1301
        
 
1302
f_ulBufferIndex                 Allocated entry in buffer playout list.
 
1303
f_ulBufferBase                  Allocated external memory block for the buffer.
 
1304
f_fReleaseListStruct    Free the list structure.
 
1305
 
 
1306
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
1307
#if !SKIP_Oct6100ApiReleaseBufferResources
 
1308
UINT32 Oct6100ApiReleaseBufferResources(
 
1309
                                IN OUT  tPOCT6100_INSTANCE_API                  f_pApiInstance,
 
1310
                                IN              UINT32                                                  f_ulBufferIndex,
 
1311
                                IN              UINT32                                                  f_ulBufferBase,
 
1312
                                IN              BOOL                                                    f_fReleaseListStruct )
 
1313
{
 
1314
        tPOCT6100_SHARED_INFO   pSharedInfo;
 
1315
        tPOCT6100_API_BUFFER    pBufEntry;
 
1316
        UINT32  ulResult;
 
1317
        UINT32  ulBufferSize;
 
1318
 
 
1319
        /* Obtain local pointer to shared portion of instance. */
 
1320
        pSharedInfo = f_pApiInstance->pSharedInfo;
 
1321
 
 
1322
        /* Free the external memory reserved for the buffer. */
 
1323
        ulResult = Oct6100ApiReleaseBufferPlayoutMemory( f_pApiInstance, f_ulBufferBase );
 
1324
        if ( ulResult != cOCT6100_ERR_OK )
 
1325
                return cOCT6100_ERR_FATAL_3E;
 
1326
 
 
1327
        /* Release the entry from the buffer list. */
 
1328
        if ( f_fReleaseListStruct == TRUE )
 
1329
                ulResult = Oct6100ApiReleaseBufPlayoutListEntry( f_pApiInstance, f_ulBufferIndex );
 
1330
        if ( ulResult != cOCT6100_ERR_OK )
 
1331
                return ulResult;
 
1332
 
 
1333
        mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBufEntry, f_ulBufferIndex );
 
1334
 
 
1335
        /* Save buffer size before releasing that entry, will be needed to calculate the amount of */
 
1336
        /* free memory left for the user. */
 
1337
        ulBufferSize = pBufEntry->ulBufferSize;
 
1338
        
 
1339
        /* Flag the buffer entry as free. */
 
1340
        pBufEntry->fReserved = FALSE;
 
1341
 
 
1342
        /* Decrement the number of buffer loaded into the chip. */
 
1343
        f_pApiInstance->pSharedInfo->ChipStats.usNumberPlayoutBuffers--;
 
1344
 
 
1345
        /* Refresh the amount of memory used by buffer playout. */
 
1346
        /* Reserved size is divisible by 64. */
 
1347
        if ( ulBufferSize % 64 )
 
1348
                ulBufferSize = ulBufferSize + ( 64 - ( ulBufferSize % 64 ) );
 
1349
        f_pApiInstance->pSharedInfo->ChipStats.ulPlayoutMemUsed -= ulBufferSize;
 
1350
 
 
1351
        return cOCT6100_ERR_OK;
 
1352
}
 
1353
#endif
 
1354
 
 
1355
 
 
1356
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
1357
 
 
1358
Function:               Oct6100BufferPlayoutAddSer
 
1359
 
 
1360
Description:    This function adds a buffer to a channel buffer list.
 
1361
 
 
1362
-------------------------------------------------------------------------------
 
1363
|       Argument                |       Description
 
1364
-------------------------------------------------------------------------------
 
1365
f_pApiInstance                  Pointer to API instance. This memory is used to keep the
 
1366
                                                present state of the chip and all its resources.
 
1367
 
 
1368
f_pBufferPlayoutAdd             Pointer to buffer playout add structure.
 
1369
 
 
1370
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
1371
#if !SKIP_Oct6100BufferPlayoutAddSer
 
1372
UINT32 Oct6100BufferPlayoutAddSer(
 
1373
                                IN OUT  tPOCT6100_INSTANCE_API                          f_pApiInstance,
 
1374
                                IN OUT  tPOCT6100_BUFFER_PLAYOUT_ADD            f_pBufferPlayoutAdd )
 
1375
{
 
1376
        UINT32  ulBufferIndex;
 
1377
        UINT32  ulChannelIndex;
 
1378
        UINT32  ulResult;
 
1379
 
 
1380
        /* Check the user's configuration of the buffer for errors. */
 
1381
        ulResult = Oct6100ApiCheckPlayoutAddParams( f_pApiInstance, f_pBufferPlayoutAdd, &ulChannelIndex, &ulBufferIndex );
 
1382
        if ( ulResult != cOCT6100_ERR_OK )
 
1383
                return ulResult;
 
1384
 
 
1385
        /* Write to  all resources needed to activate buffer playout. */
 
1386
        ulResult = Oct6100ApiWriteBufferAddStructs( f_pApiInstance, f_pBufferPlayoutAdd, ulChannelIndex, ulBufferIndex );
 
1387
        if ( ulResult != cOCT6100_ERR_OK )
 
1388
                return ulResult;
 
1389
 
 
1390
        return cOCT6100_ERR_OK;
 
1391
}
 
1392
#endif
 
1393
 
 
1394
 
 
1395
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
1396
 
 
1397
Function:               Oct6100ApiCheckPlayoutAddParams
 
1398
 
 
1399
Description:    Check the validity of the channel and buffer requested.
 
1400
 
 
1401
-------------------------------------------------------------------------------
 
1402
|       Argument                |       Description
 
1403
-------------------------------------------------------------------------------
 
1404
f_pApiInstance                  Pointer to API instance. This memory is used to keep the
 
1405
                                                present state of the chip and all its resources.
 
1406
 
 
1407
f_pBufferPlayoutAdd             Pointer to buffer playout add structure.  
 
1408
f_pulChannelIndex               Pointer to the channel index of the selected channel.
 
1409
f_pulBufferIndex                Pointer to the buffer index within the API's buffer list.
 
1410
 
 
1411
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
1412
#if !SKIP_Oct6100ApiCheckPlayoutAddParams
 
1413
UINT32 Oct6100ApiCheckPlayoutAddParams(
 
1414
                                IN OUT  tPOCT6100_INSTANCE_API                          f_pApiInstance,
 
1415
                                IN              tPOCT6100_BUFFER_PLAYOUT_ADD            f_pBufferPlayoutAdd,
 
1416
                                OUT             PUINT32                                                         f_pulChannelIndex, 
 
1417
                                OUT             PUINT32                                                         f_pulBufferIndex )
 
1418
{
 
1419
        tPOCT6100_API_BUFFER                    pBufferEntry;
 
1420
        tPOCT6100_API_CHANNEL                   pEchoChannel;
 
1421
        UINT32  ulEntryOpenCnt;
 
1422
 
 
1423
        /* Check for errors. */
 
1424
        if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxPlayoutBuffers == 0 )
 
1425
                return cOCT6100_ERR_BUFFER_PLAYOUT_DISABLED;
 
1426
        
 
1427
        if ( f_pBufferPlayoutAdd->ulChannelHndl == cOCT6100_INVALID_HANDLE )
 
1428
                return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID;
 
1429
 
 
1430
        if ( f_pBufferPlayoutAdd->ulPlayoutPort != cOCT6100_CHANNEL_PORT_ROUT && 
 
1431
                 f_pBufferPlayoutAdd->ulPlayoutPort != cOCT6100_CHANNEL_PORT_SOUT )
 
1432
                return cOCT6100_ERR_BUFFER_PLAYOUT_PLAYOUT_PORT;
 
1433
 
 
1434
        if ( f_pBufferPlayoutAdd->fRepeat != TRUE && f_pBufferPlayoutAdd->fRepeat != FALSE )
 
1435
                return cOCT6100_ERR_BUFFER_PLAYOUT_ADD_REPEAT;
 
1436
 
 
1437
        if ( f_pBufferPlayoutAdd->fRepeat == TRUE )
 
1438
        {
 
1439
                if ( f_pBufferPlayoutAdd->ulRepeatCount != cOCT6100_REPEAT_INFINITELY )
 
1440
                {
 
1441
                        if ( f_pBufferPlayoutAdd->ulRepeatCount == 0x0 
 
1442
                                || f_pBufferPlayoutAdd->ulRepeatCount > cOCT6100_REPEAT_MAX)
 
1443
                        {
 
1444
                                return cOCT6100_ERR_BUFFER_PLAYOUT_ADD_REPEAT_COUNT;
 
1445
                        }
 
1446
                }
 
1447
        }
 
1448
 
 
1449
        if ( f_pBufferPlayoutAdd->ulMixingMode != cOCT6100_MIXING_0_DB &&
 
1450
                 f_pBufferPlayoutAdd->ulMixingMode != cOCT6100_MIXING_MINUS_6_DB &&
 
1451
                 f_pBufferPlayoutAdd->ulMixingMode != cOCT6100_MIXING_MINUS_12_DB &&
 
1452
                 f_pBufferPlayoutAdd->ulMixingMode != cOCT6100_MIXING_MUTE )
 
1453
                return cOCT6100_ERR_BUFFER_PLAYOUT_ADD_MIXING;
 
1454
 
 
1455
        if ( ( f_pBufferPlayoutAdd->lGainDb < -24 )
 
1456
                || ( f_pBufferPlayoutAdd->lGainDb > 24 ) )
 
1457
                return cOCT6100_ERR_BUFFER_PLAYOUT_ADD_GAIN_DB;
 
1458
 
 
1459
        /*=====================================================================*/
 
1460
        /* Check the channel handle. */
 
1461
 
 
1462
        if ( (f_pBufferPlayoutAdd->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL )
 
1463
                return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID;
 
1464
 
 
1465
        *f_pulChannelIndex = f_pBufferPlayoutAdd->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK;
 
1466
        if ( *f_pulChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels )
 
1467
                return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID;
 
1468
 
 
1469
        mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChannel, *f_pulChannelIndex )
 
1470
 
 
1471
        /* Extract the entry open count from the provided handle. */
 
1472
        ulEntryOpenCnt = (f_pBufferPlayoutAdd->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK;
 
1473
 
 
1474
        /* Check for errors. */
 
1475
        if ( pEchoChannel->fReserved != TRUE )
 
1476
                return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_NOT_OPEN;
 
1477
        if ( ulEntryOpenCnt != pEchoChannel->byEntryOpenCnt )
 
1478
                return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID;
 
1479
 
 
1480
        /* Check if repeat flag has been used for this port. */
 
1481
        if ( ( ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) && ( pEchoChannel->fRinBufPlayoutRepeatUsed == TRUE ) )
 
1482
                || ( ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) && ( pEchoChannel->fSoutBufPlayoutRepeatUsed == TRUE ) ) )
 
1483
                return cOCT6100_ERR_BUFFER_PLAYOUT_REPEAT_USED;
 
1484
 
 
1485
        /*=====================================================================*/
 
1486
 
 
1487
        /*=====================================================================*/
 
1488
        /* Check the buffer information. */
 
1489
 
 
1490
        *f_pulBufferIndex = f_pBufferPlayoutAdd->ulBufferIndex;
 
1491
        if ( *f_pulBufferIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxPlayoutBuffers )
 
1492
                return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_INDEX;
 
1493
 
 
1494
        mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBufferEntry, *f_pulBufferIndex )
 
1495
 
 
1496
        if ( pBufferEntry->fReserved != TRUE )
 
1497
                return cOCT6100_ERR_BUFFER_PLAYOUT_NOT_OPEN;
 
1498
 
 
1499
        /* Check if the play length is not larger then the currently uploaded buffer. */
 
1500
        if ( ( f_pBufferPlayoutAdd->ulBufferLength > pBufferEntry->ulBufferSize ) &&
 
1501
                  ( f_pBufferPlayoutAdd->ulBufferLength != cOCT6100_AUTO_SELECT ) )
 
1502
                return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_SIZE;
 
1503
 
 
1504
        if( f_pBufferPlayoutAdd->ulBufferLength != cOCT6100_AUTO_SELECT )
 
1505
        {
 
1506
                if ( f_pBufferPlayoutAdd->ulBufferLength < cOCT6100_MINIMUM_BUFFER_SIZE )
 
1507
                        return cOCT6100_ERR_BUFFER_PLAYOUT_TOO_SMALL;
 
1508
 
 
1509
                if ( ( f_pBufferPlayoutAdd->ulBufferLength % cOCT6100_BUFFER_SIZE_GRANULARITY ) != 0 )
 
1510
                        return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_SIZE;
 
1511
        }
 
1512
 
 
1513
        /*=====================================================================*/
 
1514
 
 
1515
        return cOCT6100_ERR_OK;
 
1516
}
 
1517
#endif
 
1518
 
 
1519
 
 
1520
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
1521
 
 
1522
Function:               Oct6100ApiWriteBufferAddStructs
 
1523
 
 
1524
Description:    Write the buffer playout event in the channel's port playout
 
1525
                                circular buffer.
 
1526
 
 
1527
-------------------------------------------------------------------------------
 
1528
|       Argument                |       Description
 
1529
-------------------------------------------------------------------------------
 
1530
f_pApiInstance                  Pointer to API instance. This memory is used to keep the
 
1531
                                                present state of the chip and all its resources.
 
1532
        
 
1533
f_pBufferPlayoutAdd             Pointer to buffer playout add structure.  
 
1534
f_ulChannelIndex                Index of the channel on which the buffer is to be added.
 
1535
f_ulBufferIndex                 Index of the buffer structure within the API's buffer list.
 
1536
 
 
1537
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
1538
#if !SKIP_Oct6100ApiWriteBufferAddStructs
 
1539
UINT32 Oct6100ApiWriteBufferAddStructs(
 
1540
                                IN OUT  tPOCT6100_INSTANCE_API                          f_pApiInstance,
 
1541
                                IN              tPOCT6100_BUFFER_PLAYOUT_ADD            f_pBufferPlayoutAdd,
 
1542
                                IN              UINT32                                                          f_ulChannelIndex, 
 
1543
                                IN              UINT32                                                          f_ulBufferIndex )
 
1544
{
 
1545
        tPOCT6100_API_BUFFER            pBufferEntry;
 
1546
        tPOCT6100_API_CHANNEL           pEchoChannel;
 
1547
        tPOCT6100_SHARED_INFO           pSharedInfo;
 
1548
        tOCT6100_READ_PARAMS            ReadParams;
 
1549
        UINT32  ulResult;
 
1550
        UINT32  ulTempData;
 
1551
        UINT32  ulEventBuffer;
 
1552
 
 
1553
        UINT32  ulReadPtrBytesOfst;
 
1554
        UINT32  ulReadPtrBitOfst;
 
1555
        UINT32  ulReadPtrFieldSize;
 
1556
 
 
1557
        UINT32  ulWritePtrBytesOfst;
 
1558
        UINT32  ulWritePtrBitOfst;
 
1559
        UINT32  ulWritePtrFieldSize;
 
1560
 
 
1561
        UINT32  ulWritePtr;
 
1562
        UINT32  ulReadPtr;
 
1563
 
 
1564
        UINT32  ulPlayoutBaseAddress;
 
1565
        UINT32  ulAddress;
 
1566
        UINT32  ulEventIndex;
 
1567
        UINT32  ulMask;
 
1568
 
 
1569
        UINT32  ulRepeatCount = 0;
 
1570
        BOOL    fRepeatCountSet = FALSE;
 
1571
        UINT32  ulDurationModulo = 0;
 
1572
        UINT32  ulEventsToCreate = 1;
 
1573
        UINT32  ulBufferDurationMs;
 
1574
        
 
1575
        UINT32  ulBufferLength;
 
1576
        UINT16  usTempData = 0;
 
1577
 
 
1578
        UINT16  usReadData;
 
1579
        UINT32  ulChipWritePtr;
 
1580
        UINT32  ulReadData;
 
1581
        UINT32  ulLoopCnt = 0;
 
1582
        BOOL    fStillPlaying = TRUE;
 
1583
        BOOL    fCheckHardStop = FALSE;
 
1584
        BOOL    fOldBufferPlayoutVersion = FALSE;
 
1585
 
 
1586
        UINT32                  aulWaitTime[ 2 ];
 
1587
 
 
1588
        /* Obtain local pointer to shared portion of instance. */
 
1589
        pSharedInfo = f_pApiInstance->pSharedInfo;
 
1590
 
 
1591
        mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChannel, f_ulChannelIndex );
 
1592
        mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBufferEntry, f_ulBufferIndex );
 
1593
 
 
1594
        /* Select the buffer of interest. */
 
1595
        if ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT )
 
1596
        {
 
1597
                ulEventBuffer = pSharedInfo->MemoryMap.ulChanMainRinPlayoutMemOfst;
 
1598
                ulWritePtr = pEchoChannel->ulRinBufWritePtr;
 
1599
 
 
1600
                ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.usDwordOffset * 4;
 
1601
                ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byBitOffset;
 
1602
                ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byFieldSize;
 
1603
 
 
1604
                ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.usDwordOffset * 4;
 
1605
                ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byBitOffset;
 
1606
                ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byFieldSize;
 
1607
        }
 
1608
        else /* f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */
 
1609
        {
 
1610
                ulEventBuffer = pSharedInfo->MemoryMap.ulChanMainSoutPlayoutMemOfst;
 
1611
                ulWritePtr = pEchoChannel->ulSoutBufWritePtr;
 
1612
 
 
1613
                ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.usDwordOffset * 4;
 
1614
                ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byBitOffset;
 
1615
                ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byFieldSize;
 
1616
 
 
1617
                ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.usDwordOffset * 4;
 
1618
                ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byBitOffset;
 
1619
                ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byFieldSize;
 
1620
        }
 
1621
 
 
1622
        /*=======================================================================*/
 
1623
        /* Calculate the repeat count. */
 
1624
 
 
1625
        /* The buffer length is either the total buffer size or the value specified by the user */
 
1626
        if ( f_pBufferPlayoutAdd->ulBufferLength == cOCT6100_AUTO_SELECT )
 
1627
        {
 
1628
                ulBufferLength = pBufferEntry->ulBufferSize;
 
1629
        }
 
1630
        else
 
1631
        {
 
1632
                ulBufferLength = f_pBufferPlayoutAdd->ulBufferLength;
 
1633
        }
 
1634
 
 
1635
        if ( f_pBufferPlayoutAdd->ulDuration != cOCT6100_INVALID_VALUE )
 
1636
        {
 
1637
                /* With duration and buffer length, we can find the number of times we must repeat playing this buffer. */
 
1638
                ulBufferDurationMs = ulBufferLength / cOCT6100_SAMPLES_PER_MS;
 
1639
                ulRepeatCount = f_pBufferPlayoutAdd->ulDuration / ulBufferDurationMs;
 
1640
                fRepeatCountSet = TRUE;
 
1641
 
 
1642
                /* Check if buffer is larger then asked duration. */
 
1643
                if ( ulRepeatCount != 0x0 )
 
1644
                {
 
1645
                        /* We might have to create more then 1 event to accomodate for the repeat-max limit. */
 
1646
                        ulEventsToCreate = ( ulRepeatCount / cOCT6100_REPEAT_MAX ) + 1;
 
1647
                }
 
1648
                else
 
1649
                {
 
1650
                        /* No repeat event.  Maybe only the duration modulo! */
 
1651
                        ulEventsToCreate = 0x0;
 
1652
                }
 
1653
 
 
1654
                /* Check if must create a second event for a buffer that cannot be played completely. */
 
1655
                ulDurationModulo = f_pBufferPlayoutAdd->ulDuration % ulBufferDurationMs;
 
1656
                if ( ulDurationModulo != 0x0 )
 
1657
                {
 
1658
                        ulDurationModulo *= cOCT6100_SAMPLES_PER_MS;
 
1659
                        if ( ulDurationModulo / cOCT6100_BUFFER_SIZE_GRANULARITY )
 
1660
                        {
 
1661
                                /* Round the modulo to be on a buffer size granularity. */
 
1662
                                /* This will round down. */
 
1663
                                ulDurationModulo = ( ulDurationModulo / cOCT6100_BUFFER_SIZE_GRANULARITY ) * cOCT6100_BUFFER_SIZE_GRANULARITY;
 
1664
 
 
1665
                                /* If the event about to be created is smaller then the minimum buffer size, */
 
1666
                                /* round up to the minimum required by the hardware. */
 
1667
                                if ( ulDurationModulo < cOCT6100_MINIMUM_BUFFER_SIZE )
 
1668
                                        ulDurationModulo = cOCT6100_MINIMUM_BUFFER_SIZE;
 
1669
                                ulEventsToCreate++;
 
1670
                        }
 
1671
                        else
 
1672
                        {
 
1673
                                /* The modulo is too small to be played.  Skip. */
 
1674
                                ulDurationModulo = 0;
 
1675
                        }
 
1676
                }
 
1677
        }
 
1678
        else if ( f_pBufferPlayoutAdd->fRepeat == TRUE 
 
1679
                && f_pBufferPlayoutAdd->ulRepeatCount != cOCT6100_REPEAT_INFINITELY )
 
1680
        {
 
1681
                /* The repeat count is set directly from the user. */
 
1682
                ulRepeatCount = f_pBufferPlayoutAdd->ulRepeatCount;
 
1683
                fRepeatCountSet = TRUE;
 
1684
        }
 
1685
        
 
1686
        /*=======================================================================*/
 
1687
 
 
1688
        /* Set the playout feature base address. */
 
1689
        ulPlayoutBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_ulChannelIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst;
 
1690
 
 
1691
        /* Read the read pointer. */
 
1692
        ulAddress = ulPlayoutBaseAddress + ulReadPtrBytesOfst;
 
1693
 
 
1694
        /* Must read in memory directly since this value is changed by hardware. */
 
1695
        ulResult = Oct6100ApiReadDword( f_pApiInstance, ulAddress, &ulTempData );
 
1696
        if ( ulResult != cOCT6100_ERR_OK )
 
1697
                return ulResult;
 
1698
        
 
1699
        mOCT6100_CREATE_FEATURE_MASK( ulReadPtrFieldSize, ulReadPtrBitOfst, &ulMask );
 
1700
        
 
1701
        /* Store the read pointer. */
 
1702
        ulReadPtr = ( ulTempData & ulMask ) >> ulReadPtrBitOfst;
 
1703
 
 
1704
        /* Compare the pointers...  Are they different?  If so, there is something already in the list.  */
 
1705
        if ( ulReadPtr != ulWritePtr )
 
1706
        {
 
1707
                /* Check if there is enough room for the playout events. */
 
1708
                if ( ( pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip == TRUE )
 
1709
                        && ( pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip == TRUE ) )
 
1710
                {
 
1711
                        /* 127 or 31 events image. */
 
1712
                        if ( (UINT8)( ( ulWritePtr - ulReadPtr ) & ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - 1 ) ) >= ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - (UINT8)ulEventsToCreate ) )
 
1713
                                fCheckHardStop = TRUE;
 
1714
                }
 
1715
                else
 
1716
                {
 
1717
                        /* Old 31 events image. */
 
1718
                        if ( ( ( ulWritePtr - ulReadPtr ) & 0x1F ) >= ( 0x20 - ulEventsToCreate ) )
 
1719
                                fCheckHardStop = TRUE;
 
1720
 
 
1721
                        fOldBufferPlayoutVersion = TRUE;
 
1722
                }
 
1723
 
 
1724
                if ( fCheckHardStop == TRUE )
 
1725
                {
 
1726
                        /* Ok.  From what was read, the list is full.  But we might still have a chance if the hard-stop */
 
1727
                        /* version was used.  In this case, some of the buffers in the list might */
 
1728
                        /* become free in a couple of milliseconds, so try to wait for this. */
 
1729
                        
 
1730
                        if ( ( ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) && ( pEchoChannel->fRinHardStop == TRUE ) )
 
1731
                                || ( ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) && ( pEchoChannel->fSoutHardStop == TRUE ) ) )
 
1732
                        {
 
1733
                                /* Read the 'chip' write pointer in the hardware. */
 
1734
                                ReadParams.pProcessContext = f_pApiInstance->pProcessContext;
 
1735
 
 
1736
                                ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
 
1737
                                ReadParams.pusReadData = &usReadData;
 
1738
                                ReadParams.ulReadAddress = ulPlayoutBaseAddress + ulReadPtrBytesOfst;
 
1739
 
 
1740
                                /* Get the write pointer in the chip. */
 
1741
                                ulAddress = ulPlayoutBaseAddress + ulWritePtrBytesOfst;
 
1742
 
 
1743
                                mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, pEchoChannel, ulAddress, &ulReadData, ulResult );
 
1744
                                if ( ulResult != cOCT6100_ERR_OK )
 
1745
                                        return ulResult;
 
1746
 
 
1747
                                mOCT6100_CREATE_FEATURE_MASK( ulWritePtrFieldSize, ulWritePtrBitOfst, &ulMask );
 
1748
 
 
1749
                                /* Store the write pointer. */
 
1750
                                ulChipWritePtr = ( ulReadData & ulMask ) >> ulWritePtrBitOfst;
 
1751
 
 
1752
                                /* Optimize this access by only reading the word we are interested in. */
 
1753
                                if ( ulReadPtrBitOfst < 16 )
 
1754
                                        ReadParams.ulReadAddress += 2;
 
1755
 
 
1756
                                while( fStillPlaying == TRUE )
 
1757
                                {                               
 
1758
                                        /* Read the read pointer until equals to the write pointer. */
 
1759
                                        mOCT6100_DRIVER_READ_API( ReadParams, ulResult )
 
1760
                                        if ( ulResult != cOCT6100_ERR_OK )
 
1761
                                                return ulResult;
 
1762
 
 
1763
                                        /* Move data at correct position according to what was read. */
 
1764
                                        if ( ulReadPtrBitOfst < 16 )
 
1765
                                                ulTempData = usReadData;
 
1766
                                        else
 
1767
                                                ulTempData = usReadData << 16;
 
1768
                                        
 
1769
                                        mOCT6100_CREATE_FEATURE_MASK( ulReadPtrFieldSize, ulReadPtrBitOfst, &ulMask );
 
1770
                                        
 
1771
                                        /* Store the read pointer.*/
 
1772
                                        ulReadPtr = ( ulTempData & ulMask ) >> ulReadPtrBitOfst;
 
1773
 
 
1774
                                        /* Playout has finished when the read pointer reaches the write pointer. */
 
1775
                                        if ( ulReadPtr == ulChipWritePtr )
 
1776
                                                break;
 
1777
 
 
1778
                                        ulLoopCnt++;
 
1779
                                        if ( ulLoopCnt > cOCT6100_MAX_LOOP )
 
1780
                                        {
 
1781
                                                return cOCT6100_ERR_FATAL_E7;
 
1782
                                        }
 
1783
 
 
1784
                                        aulWaitTime[ 0 ] = 100;
 
1785
                                        aulWaitTime[ 1 ] = 0;
 
1786
                                        ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime );
 
1787
                                        if ( ulResult != cOCT6100_ERR_OK )
 
1788
                                                return ulResult;                        
 
1789
                                }
 
1790
 
 
1791
                                /* Clear hard-stop flag. */
 
1792
                                if ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT )
 
1793
                                {
 
1794
                                        /* No hard stop for now. */
 
1795
                                        pEchoChannel->fRinHardStop = FALSE;
 
1796
                                }
 
1797
                                else /* if ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) */
 
1798
                                {
 
1799
                                        /* No hard stop for now. */
 
1800
                                        pEchoChannel->fSoutHardStop = FALSE;
 
1801
                                }
 
1802
 
 
1803
                                /* Now check again if the event can be added... */
 
1804
                                if ( fOldBufferPlayoutVersion == FALSE )
 
1805
                                {
 
1806
                                        if ( (UINT8)( ( ulWritePtr - ulReadPtr ) & ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - 1 ) ) >= ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - (UINT8)ulEventsToCreate ) )
 
1807
                                                return cOCT6100_ERR_BUFFER_PLAYOUT_ADD_EVENT_BUF_FULL;
 
1808
                                }
 
1809
                                else /* if ( fOldBufferPlayoutVersion == TRUE ) */
 
1810
                                {
 
1811
                                        /* Old 31 events image. */
 
1812
                                        if ( ( ( ulWritePtr - ulReadPtr ) & 0x1F ) >= ( 0x20 - ulEventsToCreate ) )
 
1813
                                                return cOCT6100_ERR_BUFFER_PLAYOUT_ADD_EVENT_BUF_FULL;
 
1814
                                }
 
1815
 
 
1816
                                /* Good, at least another buffer can be added!  Add the buffer to the list. */
 
1817
                        }
 
1818
                        else
 
1819
                        {
 
1820
                                /* Well the list is full! */
 
1821
                                return cOCT6100_ERR_BUFFER_PLAYOUT_ADD_EVENT_BUF_FULL;
 
1822
                        }
 
1823
                }
 
1824
        }
 
1825
 
 
1826
        /*=======================================================================*/
 
1827
        /* Write the events. */
 
1828
 
 
1829
        for ( ulEventIndex = 0; ulEventIndex < ulEventsToCreate; ulEventIndex ++  )
 
1830
        {
 
1831
                /* Set the playout event base address. */
 
1832
                if ( ( pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip == TRUE )
 
1833
                        && ( pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip == TRUE ) )
 
1834
                {
 
1835
                        /* 127 or 31 events image. */
 
1836
                        ulAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + (f_ulChannelIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + ulEventBuffer + (cOCT6100_PLAYOUT_EVENT_MEM_SIZE * (ulWritePtr & ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - 1 )));
 
1837
                }
 
1838
                else
 
1839
                {
 
1840
                        /* Old 31 events image. */
 
1841
                        ulAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + (f_ulChannelIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + ulEventBuffer + (cOCT6100_PLAYOUT_EVENT_MEM_SIZE * (ulWritePtr & 0x1F));
 
1842
                }
 
1843
        
 
1844
                /* EVENT BASE + 0 */
 
1845
                /* Make sure the xIS and xHS bits are cleared. */
 
1846
                ulTempData = 0;
 
1847
 
 
1848
                /* Set the repeat count. */
 
1849
                if ( fRepeatCountSet == TRUE )
 
1850
                {
 
1851
                        if ( ( ulRepeatCount != 0x0 ) && ( ulRepeatCount <= cOCT6100_REPEAT_MAX ) )
 
1852
                        {
 
1853
                                /* Use repeat count directly. */
 
1854
                                ulTempData |= ulRepeatCount;
 
1855
 
 
1856
                                /* Will be used later when creating the duration modulo event. */
 
1857
                                ulRepeatCount = 0;
 
1858
                        }
 
1859
                        else if ( ulRepeatCount != 0x0 )
 
1860
                        {
 
1861
                                /* Get ready for next event. */
 
1862
                                ulRepeatCount -= cOCT6100_REPEAT_MAX;
 
1863
 
 
1864
                                /* Set maximum for this event. */
 
1865
                                ulTempData |= cOCT6100_REPEAT_MAX;
 
1866
                        }
 
1867
                        else
 
1868
                        {
 
1869
                                /* Duration modulo case.  Nothing to set here. */
 
1870
                        }
 
1871
                }
 
1872
                else /* if ( fRepeatCountSet != TRUE ) */
 
1873
                {
 
1874
                        /* Repeat only once. */
 
1875
                        ulTempData |= 0x1;
 
1876
                }
 
1877
 
 
1878
                ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulAddress, ulTempData );
 
1879
                if ( ulResult != cOCT6100_ERR_OK )
 
1880
                        return ulResult;
 
1881
 
 
1882
                /* EVENT BASE + 4 */
 
1883
                /* Set the buffer base address and playout configuration. */
 
1884
                ulAddress += 4;
 
1885
                ulTempData = pBufferEntry->ulBufferBase & 0x07FFFFFF;
 
1886
 
 
1887
                /* Set play indefinitely or loop N times. */
 
1888
                if ( ( fRepeatCountSet == FALSE ) && ( f_pBufferPlayoutAdd->fRepeat == TRUE ) )
 
1889
                {
 
1890
                        /* Repeat indefinitely. */
 
1891
                        ulTempData |= 0x1 << cOCT6100_PLAYOUT_EVENT_REPEAT_OFFSET;
 
1892
 
 
1893
                        if ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT )
 
1894
                                pEchoChannel->fRinBufPlayoutRepeatUsed = TRUE;
 
1895
                        else /* if ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) */
 
1896
                                pEchoChannel->fSoutBufPlayoutRepeatUsed = TRUE;
 
1897
                }
 
1898
                
 
1899
                /* Use loop N times feature. */
 
1900
                ulTempData |= 0x1 << cOCT6100_PLAYOUT_EVENT_LOOP_TIMES_OFFSET;
 
1901
 
 
1902
                /* Set the law.*/
 
1903
                ulTempData |= ( pBufferEntry->byBufferPcmLaw << cOCT6100_PLAYOUT_EVENT_LAW_OFFSET );
 
1904
 
 
1905
                /* Set the mixing configuration.*/
 
1906
                ulTempData |= f_pBufferPlayoutAdd->ulMixingMode << cOCT6100_PLAYOUT_EVENT_MIX_OFFSET;
 
1907
 
 
1908
                ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulAddress, ulTempData );
 
1909
                if ( ulResult != cOCT6100_ERR_OK )
 
1910
                        return ulResult;
 
1911
 
 
1912
                
 
1913
                /* EVENT BASE + 8 */
 
1914
                /* Set the buffer size and playout gain. */
 
1915
                ulAddress += 4;
 
1916
 
 
1917
                /* Check if we are setting the duration modulo.  This would be the last event and this */
 
1918
                /* event is of a very specific size. */
 
1919
                if ( ( fRepeatCountSet == TRUE ) 
 
1920
                        && ( ulEventIndex == ( ulEventsToCreate - 1 ) ) 
 
1921
                        && ( ulDurationModulo != 0x0 ) )
 
1922
                {
 
1923
                        /* The duration modulo variable contains all that is needed here. */
 
1924
                        ulBufferLength = ulDurationModulo;
 
1925
                }
 
1926
                ulTempData = ulBufferLength;
 
1927
 
 
1928
                /* Adjust playout gain. */
 
1929
                if ( f_pBufferPlayoutAdd->lGainDb != 0 )
 
1930
                {
 
1931
                        /* Convert the dB value into OctFloat format. */
 
1932
                        usTempData = Oct6100ApiDbAmpHalfToOctFloat( f_pBufferPlayoutAdd->lGainDb );
 
1933
                        ulTempData |= ( usTempData & 0xFF00 ) << 16;
 
1934
                }
 
1935
                else
 
1936
                {
 
1937
                        ulTempData |= cOCT6100_PLAYOUT_GAIN;
 
1938
                }
 
1939
 
 
1940
                ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulAddress, ulTempData );
 
1941
                if ( ulResult != cOCT6100_ERR_OK )
 
1942
                        return ulResult;
 
1943
                        
 
1944
                /* EVENT BASE + 0xC */
 
1945
                ulAddress += 4;
 
1946
                ulTempData = ( ulBufferLength - 1 ) & 0xFFFFFFC0;       /* Must be multiple of 64 bytes */
 
1947
 
 
1948
                /* Adjust playout gain. */
 
1949
                if ( f_pBufferPlayoutAdd->lGainDb != 0 )
 
1950
                {
 
1951
                        ulTempData |= ( usTempData & 0xFF ) << 24;
 
1952
                }
 
1953
 
 
1954
                ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulAddress, ulTempData );
 
1955
                if ( ulResult != cOCT6100_ERR_OK )
 
1956
                        return ulResult;
 
1957
 
 
1958
                /* Next event. */
 
1959
                ulWritePtr++;
 
1960
        }
 
1961
 
 
1962
        /*=======================================================================*/
 
1963
 
 
1964
 
 
1965
        /*=======================================================================*/
 
1966
        /* Increment the write pointer to make it point to the next empty entry. */
 
1967
 
 
1968
        if ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT )
 
1969
        {
 
1970
                pEchoChannel->ulRinBufWritePtr = ( pEchoChannel->ulRinBufWritePtr + ulEventsToCreate ) & ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - 1 );
 
1971
                /* Remember that a buffer was added on the rin port. */
 
1972
                pEchoChannel->fRinBufAdded = TRUE;
 
1973
        }
 
1974
        else /* f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */
 
1975
        {
 
1976
                pEchoChannel->ulSoutBufWritePtr = ( pEchoChannel->ulSoutBufWritePtr + ulEventsToCreate ) & ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - 1 );
 
1977
                /* Remember that a buffer was added on the sout port. */
 
1978
                pEchoChannel->fSoutBufAdded = TRUE;
 
1979
        }
 
1980
 
 
1981
        /*=======================================================================*/
 
1982
 
 
1983
        return cOCT6100_ERR_OK;
 
1984
}
 
1985
#endif
 
1986
 
 
1987
 
 
1988
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
1989
 
 
1990
Function:               Oct6100BufferPlayoutStartSer
 
1991
 
 
1992
Description:    Starts buffer playout on a channel.
 
1993
 
 
1994
-------------------------------------------------------------------------------
 
1995
|       Argument                |       Description
 
1996
-------------------------------------------------------------------------------
 
1997
f_pApiInstance                          Pointer to API instance. This memory is used to keep the
 
1998
                                                        present state of the chip and all its resources.
 
1999
 
 
2000
f_pBufferPlayoutStart           Pointer to buffer playout start structure.
 
2001
 
 
2002
f_ulPlayoutStopEventType        Playout stop event type to be generated if required.
 
2003
 
 
2004
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
2005
#if !SKIP_Oct6100BufferPlayoutStartSer
 
2006
UINT32 Oct6100BufferPlayoutStartSer(
 
2007
                                IN OUT  tPOCT6100_INSTANCE_API                          f_pApiInstance,
 
2008
                                IN OUT  tPOCT6100_BUFFER_PLAYOUT_START          f_pBufferPlayoutStart,
 
2009
                                IN              UINT32                                                          f_ulPlayoutStopEventType )
 
2010
{
 
2011
        UINT32  ulBufferIndex = 0;
 
2012
        UINT32  ulChannelIndex;
 
2013
        BOOL    fNotifyOnPlayoutStop;
 
2014
        UINT32  ulUserEventId;
 
2015
        BOOL    fAddToCurrentlyPlayingList;
 
2016
        UINT32  ulResult;
 
2017
 
 
2018
        /* Check the user's configuration of the buffer for errors. */
 
2019
        ulResult = Oct6100ApiCheckPlayoutStartParams( f_pApiInstance, f_pBufferPlayoutStart, &ulChannelIndex, &ulBufferIndex, &fNotifyOnPlayoutStop, &ulUserEventId, &fAddToCurrentlyPlayingList );
 
2020
        if ( ulResult != cOCT6100_ERR_OK )
 
2021
                return ulResult;
 
2022
 
 
2023
        /* Write to all resources needed to activate buffer playout. */
 
2024
        ulResult = Oct6100ApiWriteChanPlayoutStructs( f_pApiInstance, f_pBufferPlayoutStart, ulChannelIndex, ulBufferIndex, fNotifyOnPlayoutStop, ulUserEventId, fAddToCurrentlyPlayingList, f_ulPlayoutStopEventType );
 
2025
        if ( ulResult != cOCT6100_ERR_OK )
 
2026
                return ulResult;
 
2027
 
 
2028
        return cOCT6100_ERR_OK;
 
2029
}
 
2030
#endif
 
2031
 
 
2032
 
 
2033
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
2034
 
 
2035
Function:               Oct6100ApiCheckPlayoutStartParams
 
2036
 
 
2037
Description:    Check the validity of the channel and buffer requested.
 
2038
                                Check the validity of the flags requested.
 
2039
 
 
2040
-------------------------------------------------------------------------------
 
2041
|       Argument                |       Description
 
2042
-------------------------------------------------------------------------------
 
2043
f_pApiInstance                  Pointer to API instance. This memory is used to keep the
 
2044
                                                present state of the chip and all its resources.
 
2045
 
 
2046
f_pBufferPlayoutStart   Pointer to buffer playout start structure.  
 
2047
f_pulChannelIndex               Pointer to the channel index of the selected channel.
 
2048
f_pulBufferIndex                Pointer to the buffer index within the API's buffer list.
 
2049
f_pfNotifyOnPlayoutStop Pointer to the notify on playout stop flag.
 
2050
f_pulUserEventId                Pointer to the user event id specified.
 
2051
f_pfAllowStartIfActive  Pointer to the add to currently playing list flag.
 
2052
 
 
2053
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
2054
#if !SKIP_Oct6100ApiCheckPlayoutStartParams
 
2055
UINT32 Oct6100ApiCheckPlayoutStartParams(
 
2056
                                IN OUT  tPOCT6100_INSTANCE_API                          f_pApiInstance,
 
2057
                                IN OUT  tPOCT6100_BUFFER_PLAYOUT_START          f_pBufferPlayoutStart,
 
2058
                                OUT             PUINT32                                                         f_pulChannelIndex, 
 
2059
                                OUT             PUINT32                                                         f_pulBufferIndex,
 
2060
                                OUT             PBOOL                                                           f_pfNotifyOnPlayoutStop,
 
2061
                                OUT             PUINT32                                                         f_pulUserEventId,
 
2062
                                OUT             PBOOL                                                           f_pfAllowStartIfActive )
 
2063
{
 
2064
        tPOCT6100_API_CHANNEL   pEchoChannel;
 
2065
        UINT32                                  ulEntryOpenCnt;
 
2066
 
 
2067
        /* Check for errors. */
 
2068
        if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxPlayoutBuffers == 0 )
 
2069
                return cOCT6100_ERR_BUFFER_PLAYOUT_DISABLED;
 
2070
        
 
2071
        if ( f_pBufferPlayoutStart->ulChannelHndl == cOCT6100_INVALID_HANDLE )
 
2072
                return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID;
 
2073
 
 
2074
        if ( f_pBufferPlayoutStart->ulPlayoutPort != cOCT6100_CHANNEL_PORT_ROUT && 
 
2075
                 f_pBufferPlayoutStart->ulPlayoutPort != cOCT6100_CHANNEL_PORT_SOUT )
 
2076
                return cOCT6100_ERR_BUFFER_PLAYOUT_PLAYOUT_PORT;
 
2077
 
 
2078
        if ( f_pBufferPlayoutStart->fNotifyOnPlayoutStop != FALSE
 
2079
                && f_pBufferPlayoutStart->fNotifyOnPlayoutStop != TRUE )
 
2080
                return cOCT6100_ERR_BUFFER_PLAYOUT_NOTIFY_ON_STOP;
 
2081
 
 
2082
        if ( f_pBufferPlayoutStart->fAllowStartWhileActive != FALSE
 
2083
                && f_pBufferPlayoutStart->fAllowStartWhileActive != TRUE )
 
2084
                return cOCT6100_ERR_BUFFER_PLAYOUT_ALLOW_ACTIVE;
 
2085
 
 
2086
        /*=====================================================================*/
 
2087
        /* Check the channel handle. */
 
2088
 
 
2089
        if ( (f_pBufferPlayoutStart->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL )
 
2090
                return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID;
 
2091
 
 
2092
        *f_pulChannelIndex = f_pBufferPlayoutStart->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK;
 
2093
        if ( *f_pulChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels )
 
2094
                return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID;
 
2095
 
 
2096
        mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChannel, *f_pulChannelIndex )
 
2097
 
 
2098
        /* Extract the entry open count from the provided handle. */
 
2099
        ulEntryOpenCnt = (f_pBufferPlayoutStart->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK;
 
2100
 
 
2101
        /* Check for errors. */
 
2102
        if ( pEchoChannel->fReserved != TRUE )
 
2103
                return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_NOT_OPEN;
 
2104
        if ( ulEntryOpenCnt != pEchoChannel->byEntryOpenCnt )
 
2105
                return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID;
 
2106
 
 
2107
        /* The channel cannot be in POWER_DOWN or HT_FREEZE to start the playout. */
 
2108
        if ( ( pEchoChannel->byEchoOperationMode == cOCT6100_ECHO_OP_MODE_POWER_DOWN )
 
2109
                || ( pEchoChannel->byEchoOperationMode == cOCT6100_ECHO_OP_MODE_HT_FREEZE ) )
 
2110
                return cOCT6100_ERR_BUFFER_PLAYOUT_ECHO_OP_MODE;
 
2111
        
 
2112
        /* The channel's NLP must be enabled for playout to occur. */
 
2113
        if ( pEchoChannel->VqeConfig.fEnableNlp == FALSE )
 
2114
                return cOCT6100_ERR_BUFFER_PLAYOUT_NLP_DISABLED;
 
2115
 
 
2116
        /*=====================================================================*/
 
2117
 
 
2118
        /*=====================================================================*/
 
2119
        /* Check if the user activated the buffer playout events. */
 
2120
 
 
2121
        if ( f_pBufferPlayoutStart->fNotifyOnPlayoutStop == TRUE
 
2122
                && f_pApiInstance->pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize == 0 )
 
2123
                return cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_DISABLED;
 
2124
 
 
2125
        /*=====================================================================*/
 
2126
 
 
2127
        /*=====================================================================*/
 
2128
        /* Check if there is actually a buffer added in the list. */
 
2129
 
 
2130
        if ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT )
 
2131
        {
 
2132
                if ( pEchoChannel->fRinBufAdded == FALSE )
 
2133
                        return cOCT6100_ERR_BUFFER_PLAYOUT_LIST_EMPTY;
 
2134
        }
 
2135
        else /* if ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) */
 
2136
        {
 
2137
                if ( pEchoChannel->fSoutBufAdded == FALSE )
 
2138
                        return cOCT6100_ERR_BUFFER_PLAYOUT_LIST_EMPTY;
 
2139
        }
 
2140
 
 
2141
        /*=====================================================================*/
 
2142
 
 
2143
        /* Return the requested information. */
 
2144
        *f_pfNotifyOnPlayoutStop = f_pBufferPlayoutStart->fNotifyOnPlayoutStop;
 
2145
        *f_pulUserEventId = f_pBufferPlayoutStart->ulUserEventId;
 
2146
        *f_pfAllowStartIfActive = f_pBufferPlayoutStart->fAllowStartWhileActive;
 
2147
 
 
2148
        return cOCT6100_ERR_OK;
 
2149
}
 
2150
#endif
 
2151
 
 
2152
 
 
2153
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
2154
 
 
2155
Function:               Oct6100ApiWriteChanPlayoutStructs
 
2156
 
 
2157
Description:    Write the buffer playout event in the channel main structure.
 
2158
 
 
2159
-------------------------------------------------------------------------------
 
2160
|       Argument                |       Description
 
2161
-------------------------------------------------------------------------------
 
2162
f_pApiInstance                          Pointer to API instance. This memory is used to keep the
 
2163
                                                        present state of the chip and all its resources.
 
2164
        
 
2165
f_pBufferPlayoutStart           Pointer to buffer playout start structure.
 
2166
f_ulChannelIndex                        Index of the channel within the API's channel list.
 
2167
f_ulBufferIndex                         Index of the buffer within the API's buffer list.
 
2168
f_fNotifyOnPlayoutStop          Flag for the notify on playout stop.
 
2169
f_ulUserEventId                         User event id passed to the user when a playout event is generated.
 
2170
f_fAllowStartIfActive           Add to currently playing list flag.
 
2171
f_ulPlayoutStopEventType        Playout stop event type to be generated if required.
 
2172
 
 
2173
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
2174
#if !SKIP_Oct6100ApiWriteChanPlayoutStructs
 
2175
UINT32 Oct6100ApiWriteChanPlayoutStructs(
 
2176
                                IN OUT  tPOCT6100_INSTANCE_API                          f_pApiInstance,
 
2177
                                IN              tPOCT6100_BUFFER_PLAYOUT_START          f_pBufferPlayoutStart,
 
2178
                                IN              UINT32                                                          f_ulChannelIndex, 
 
2179
                                IN              UINT32                                                          f_ulBufferIndex,
 
2180
                                IN              BOOL                                                            f_fNotifyOnPlayoutStop,
 
2181
                                IN              UINT32                                                          f_ulUserEventId,
 
2182
                                IN              BOOL                                                            f_fAllowStartIfActive,
 
2183
                                IN              UINT32                                                          f_ulPlayoutStopEventType )
 
2184
{
 
2185
        tPOCT6100_API_BUFFER                    pBufferEntry;
 
2186
        tPOCT6100_API_CHANNEL                   pEchoChannel;
 
2187
        tPOCT6100_SHARED_INFO                   pSharedInfo;
 
2188
        tOCT6100_READ_PARAMS                    ReadParams;
 
2189
        
 
2190
        UINT32  ulResult;
 
2191
 
 
2192
        UINT32  ulWritePtr;
 
2193
        UINT32  ulChipWritePtr;
 
2194
        PUINT32 pulSkipPtr;
 
2195
        UINT32  ulWritePtrBytesOfst;
 
2196
        UINT32  ulSkipPtrBytesOfst;
 
2197
        UINT32  ulWritePtrBitOfst;
 
2198
        UINT32  ulSkipPtrBitOfst;
 
2199
        UINT32  ulWritePtrFieldSize;
 
2200
        UINT32  ulSkipPtrFieldSize;
 
2201
 
 
2202
        UINT32  ulIgnoreBytesOfst;
 
2203
        UINT32  ulIgnoreBitOfst;
 
2204
        UINT32  ulIgnoreFieldSize;
 
2205
        
 
2206
        UINT32  ulHardSkipBytesOfst;
 
2207
        UINT32  ulHardSkipBitOfst;
 
2208
        UINT32  ulHardSkipFieldSize;
 
2209
 
 
2210
        UINT32  ulReadPtrBytesOfst;
 
2211
        UINT32  ulReadPtrBitOfst;
 
2212
        UINT32  ulReadPtrFieldSize;
 
2213
 
 
2214
        UINT32  ulPlayoutBaseAddress;
 
2215
        UINT32  ulAddress;
 
2216
        UINT32  ulTempData;
 
2217
        UINT32  ulMask;
 
2218
        UINT32  ulReadData;
 
2219
        UINT32  ulReadPtr;
 
2220
        UINT32  ulLoopCnt = 0;
 
2221
 
 
2222
        UINT16  usReadData;
 
2223
 
 
2224
        BOOL    fBufferPlayoutStopDetected;
 
2225
        BOOL    fWriteSkipPtr = FALSE;
 
2226
        BOOL    fStillPlaying = TRUE;
 
2227
 
 
2228
        UINT32                  aulWaitTime[ 2 ];
 
2229
 
 
2230
        /* Obtain local pointer to shared portion of instance. */
 
2231
        pSharedInfo = f_pApiInstance->pSharedInfo;
 
2232
 
 
2233
        mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChannel, f_ulChannelIndex );
 
2234
        mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBufferEntry, f_ulBufferIndex );
 
2235
 
 
2236
        /* First off, check for buffer playout events, if requested for this channel/port. */
 
2237
        /* At the same time, if requested, check that the playout has stopped for this channel/port. */
 
2238
        if ( ( ( pEchoChannel->fRinBufPlaying == TRUE )
 
2239
                        && ( ( pEchoChannel->fRinBufPlayoutNotifyOnStop == TRUE ) || ( f_fAllowStartIfActive == FALSE ) )
 
2240
                        && ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) )
 
2241
                || ( ( ( pEchoChannel->fSoutBufPlaying == TRUE ) || ( f_fAllowStartIfActive == FALSE ) )
 
2242
                        && ( pEchoChannel->fSoutBufPlayoutNotifyOnStop == TRUE )
 
2243
                        && ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) ) )
 
2244
        {
 
2245
                /* Buffer playout might still be going on for this channel/port. */
 
2246
                ulResult = Oct6100BufferPlayoutCheckForSpecificEvent(   f_pApiInstance, 
 
2247
                                                                                                                                f_ulChannelIndex, 
 
2248
                                                                                                                                f_pBufferPlayoutStart->ulPlayoutPort,
 
2249
                                                                                                                                pEchoChannel->fRinBufPlayoutNotifyOnStop, 
 
2250
                                                                                                                                &fBufferPlayoutStopDetected );
 
2251
                if ( ulResult != cOCT6100_ERR_OK )
 
2252
                        return ulResult;
 
2253
 
 
2254
                /* Check if the user requested to only start if playout is over.  Return an error if */
 
2255
                /* buffer playout is still going on on this channel/port. */
 
2256
                if ( ( f_fAllowStartIfActive == FALSE ) && ( fBufferPlayoutStopDetected == FALSE ) )
 
2257
                {
 
2258
                        /* No go!  User should wait for the current list to stop, or call the */
 
2259
                        /* Oct6100BufferPlayoutStop function. */
 
2260
                        return cOCT6100_ERR_BUFFER_PLAYOUT_STILL_ACTIVE;
 
2261
                }
 
2262
        }
 
2263
 
 
2264
        /* Select the buffer of interest. */
 
2265
        if ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT )
 
2266
        {
 
2267
                ulWritePtr  = pEchoChannel->ulRinBufWritePtr;
 
2268
                pulSkipPtr      = &pEchoChannel->ulRinBufSkipPtr;
 
2269
 
 
2270
                ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.usDwordOffset * 4;
 
2271
                ulSkipPtrBytesOfst  = pSharedInfo->MemoryMap.PlayoutRinSkipPtrOfst.usDwordOffset * 4;
 
2272
                ulIgnoreBytesOfst       = pSharedInfo->MemoryMap.PlayoutRinIgnoreSkipCleanOfst.usDwordOffset * 4;
 
2273
                ulHardSkipBytesOfst     = pSharedInfo->MemoryMap.PlayoutRinHardSkipOfst.usDwordOffset * 4;
 
2274
                ulReadPtrBytesOfst      = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.usDwordOffset * 4;
 
2275
 
 
2276
                ulWritePtrBitOfst       = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byBitOffset;
 
2277
                ulSkipPtrBitOfst        = pSharedInfo->MemoryMap.PlayoutRinSkipPtrOfst.byBitOffset;
 
2278
                ulIgnoreBitOfst         = pSharedInfo->MemoryMap.PlayoutRinIgnoreSkipCleanOfst.byBitOffset;
 
2279
                ulHardSkipBitOfst       = pSharedInfo->MemoryMap.PlayoutRinHardSkipOfst.byBitOffset;
 
2280
                ulReadPtrBitOfst        = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byBitOffset;
 
2281
 
 
2282
                ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byFieldSize;
 
2283
                ulSkipPtrFieldSize      = pSharedInfo->MemoryMap.PlayoutRinSkipPtrOfst.byFieldSize;
 
2284
                ulIgnoreFieldSize       = pSharedInfo->MemoryMap.PlayoutRinIgnoreSkipCleanOfst.byFieldSize;
 
2285
                ulHardSkipFieldSize     = pSharedInfo->MemoryMap.PlayoutRinHardSkipOfst.byFieldSize;
 
2286
                ulReadPtrFieldSize      = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byFieldSize;
 
2287
        }
 
2288
        else /* f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */
 
2289
        {
 
2290
                ulWritePtr      = pEchoChannel->ulSoutBufWritePtr;
 
2291
                pulSkipPtr      = &pEchoChannel->ulSoutBufSkipPtr;
 
2292
 
 
2293
                ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.usDwordOffset * 4;
 
2294
                ulSkipPtrBytesOfst  = pSharedInfo->MemoryMap.PlayoutSoutSkipPtrOfst.usDwordOffset * 4;
 
2295
                ulIgnoreBytesOfst       = pSharedInfo->MemoryMap.PlayoutSoutIgnoreSkipCleanOfst.usDwordOffset * 4;
 
2296
                ulHardSkipBytesOfst     = pSharedInfo->MemoryMap.PlayoutSoutHardSkipOfst.usDwordOffset * 4;
 
2297
                ulReadPtrBytesOfst      = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.usDwordOffset * 4;
 
2298
 
 
2299
                ulWritePtrBitOfst       = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byBitOffset;
 
2300
                ulSkipPtrBitOfst        = pSharedInfo->MemoryMap.PlayoutSoutSkipPtrOfst.byBitOffset;
 
2301
                ulIgnoreBitOfst         = pSharedInfo->MemoryMap.PlayoutSoutIgnoreSkipCleanOfst.byBitOffset;
 
2302
                ulHardSkipBitOfst       = pSharedInfo->MemoryMap.PlayoutSoutHardSkipOfst.byBitOffset;
 
2303
                ulReadPtrBitOfst        = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byBitOffset;
 
2304
 
 
2305
                ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byFieldSize;
 
2306
                ulSkipPtrFieldSize      = pSharedInfo->MemoryMap.PlayoutSoutSkipPtrOfst.byFieldSize;
 
2307
                ulIgnoreFieldSize       = pSharedInfo->MemoryMap.PlayoutSoutIgnoreSkipCleanOfst.byFieldSize;
 
2308
                ulHardSkipFieldSize     = pSharedInfo->MemoryMap.PlayoutSoutHardSkipOfst.byFieldSize;
 
2309
                ulReadPtrFieldSize      = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byFieldSize;
 
2310
        }
 
2311
        
 
2312
 
 
2313
 
 
2314
        /* Set the playout feature base address. */
 
2315
        ulPlayoutBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_ulChannelIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst;
 
2316
 
 
2317
        /* Check if we must wait for stop to complete before starting a new list. */
 
2318
        if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == FALSE )
 
2319
        {
 
2320
                if ( ( ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) && ( pEchoChannel->fRinHardStop == TRUE ) )
 
2321
                        || ( ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) && ( pEchoChannel->fSoutHardStop == TRUE ) ) )
 
2322
                {
 
2323
                        /* Read the read pointer. */
 
2324
                        ReadParams.pProcessContext = f_pApiInstance->pProcessContext;
 
2325
 
 
2326
                        ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
 
2327
                        ReadParams.pusReadData = &usReadData;
 
2328
                        ReadParams.ulReadAddress = ulPlayoutBaseAddress + ulReadPtrBytesOfst;
 
2329
 
 
2330
                        /* Get the write pointer in the chip. */
 
2331
                        ulAddress = ulPlayoutBaseAddress + ulWritePtrBytesOfst;
 
2332
 
 
2333
                        mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, pEchoChannel, ulAddress, &ulReadData, ulResult );
 
2334
                        if ( ulResult != cOCT6100_ERR_OK )
 
2335
                                return ulResult;
 
2336
 
 
2337
                        mOCT6100_CREATE_FEATURE_MASK( ulWritePtrFieldSize, ulWritePtrBitOfst, &ulMask );
 
2338
 
 
2339
                        /* Store the write pointer. */
 
2340
                        ulChipWritePtr = ( ulReadData & ulMask ) >> ulWritePtrBitOfst;
 
2341
 
 
2342
                        /* Optimize this access by only reading the word we are interested in. */
 
2343
                        if ( ulReadPtrBitOfst < 16 )
 
2344
                                ReadParams.ulReadAddress += 2;
 
2345
 
 
2346
                        while( fStillPlaying == TRUE )
 
2347
                        {                               
 
2348
                                /* Read the read pointer until equals to the write pointer. */
 
2349
                                mOCT6100_DRIVER_READ_API( ReadParams, ulResult )
 
2350
                                if ( ulResult != cOCT6100_ERR_OK )
 
2351
                                        return ulResult;
 
2352
 
 
2353
                                /* Move data at correct position according to what was read. */
 
2354
                                if ( ulReadPtrBitOfst < 16 )
 
2355
                                        ulTempData = usReadData;
 
2356
                                else
 
2357
                                        ulTempData = usReadData << 16;
 
2358
                                
 
2359
                                mOCT6100_CREATE_FEATURE_MASK( ulReadPtrFieldSize, ulReadPtrBitOfst, &ulMask );
 
2360
                                
 
2361
                                /* Store the read pointer. */
 
2362
                                ulReadPtr = ( ulTempData & ulMask ) >> ulReadPtrBitOfst;
 
2363
 
 
2364
                                /* Playout has finished when the read pointer reaches the write pointer. */
 
2365
                                if ( ulReadPtr == ulChipWritePtr )
 
2366
                                        break;
 
2367
 
 
2368
                                ulLoopCnt++;
 
2369
                                if( ulLoopCnt > cOCT6100_MAX_LOOP )
 
2370
                                {
 
2371
                                        return cOCT6100_ERR_FATAL_E6;
 
2372
                                }
 
2373
 
 
2374
                                aulWaitTime[ 0 ] = 100;
 
2375
                                aulWaitTime[ 1 ] = 0;
 
2376
                                ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime );
 
2377
                                if ( ulResult != cOCT6100_ERR_OK )
 
2378
                                        return ulResult;                        
 
2379
                        }
 
2380
                }
 
2381
        }
 
2382
 
 
2383
        /* Check if must clear the skip bit. */
 
2384
        if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == FALSE )
 
2385
        {
 
2386
                if ( ( pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip == TRUE )
 
2387
                        && ( pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip == TRUE ) )
 
2388
                {
 
2389
                        /* Make sure the skip bit is cleared to start playout! */
 
2390
                        ulAddress = ulPlayoutBaseAddress + ulIgnoreBytesOfst;
 
2391
 
 
2392
                        mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, pEchoChannel, ulAddress, &ulTempData, ulResult );
 
2393
                        if ( ulResult != cOCT6100_ERR_OK )
 
2394
                                return ulResult;
 
2395
                        
 
2396
                        mOCT6100_CREATE_FEATURE_MASK( ulIgnoreFieldSize, ulIgnoreBitOfst, &ulMask );
 
2397
 
 
2398
                        /* Cleared! */
 
2399
                        ulTempData &= ( ~ulMask );
 
2400
 
 
2401
                        ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance,
 
2402
                                                                                        pEchoChannel,
 
2403
                                                                                        ulAddress,
 
2404
                                                                                        ulTempData);
 
2405
                        if ( ulResult != cOCT6100_ERR_OK )
 
2406
                                return ulResult;
 
2407
 
 
2408
                        /* Make sure the hard skip bit is cleared to start playout! */
 
2409
                        ulAddress = ulPlayoutBaseAddress + ulHardSkipBytesOfst;
 
2410
 
 
2411
                        mOCT6100_RETRIEVE_NLP_CONF_DWORD(       f_pApiInstance,
 
2412
                                                                                                pEchoChannel,
 
2413
                                                                                                ulAddress,
 
2414
                                                                                                &ulTempData,
 
2415
                                                                                                ulResult );
 
2416
                        if ( ulResult != cOCT6100_ERR_OK )
 
2417
                                return ulResult;
 
2418
                        
 
2419
                        mOCT6100_CREATE_FEATURE_MASK( ulIgnoreFieldSize, ulHardSkipBitOfst, &ulMask );
 
2420
 
 
2421
                        /* Cleared! */
 
2422
                        ulTempData &= ( ~ulMask );
 
2423
 
 
2424
                        ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance,
 
2425
                                                                                        pEchoChannel,
 
2426
                                                                                        ulAddress,
 
2427
                                                                                        ulTempData);
 
2428
                        if ( ulResult != cOCT6100_ERR_OK )
 
2429
                                return ulResult;
 
2430
                }
 
2431
        }
 
2432
 
 
2433
        /* Write the skip and write pointer to activate buffer playout. */
 
2434
 
 
2435
        /* Update the skip pointer. */
 
2436
        if ( ( pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip == FALSE )
 
2437
                || ( pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip == FALSE ) )
 
2438
        {
 
2439
                /* Old 31 events image. */
 
2440
                if ( ( ( ulWritePtr - *pulSkipPtr ) & 0x7F ) > 63 )
 
2441
                {
 
2442
                        *pulSkipPtr = ( ulWritePtr - 63 ) & 0x7F;
 
2443
                        fWriteSkipPtr = TRUE;
 
2444
                }
 
2445
        }
 
2446
        else
 
2447
        {
 
2448
                /* No need to update the skip pointer, a bit needs to be set when skipping. */
 
2449
                /* fWriteSkipPtr set to FALSE from variable declaration. */
 
2450
        }
 
2451
 
 
2452
        if ( fWriteSkipPtr == TRUE )
 
2453
        {
 
2454
                /*=======================================================================*/
 
2455
                /* Fetch and modify the skip pointer. */        
 
2456
 
 
2457
                ulAddress = ulPlayoutBaseAddress + ulSkipPtrBytesOfst;
 
2458
 
 
2459
                mOCT6100_RETRIEVE_NLP_CONF_DWORD(       f_pApiInstance,
 
2460
                                                                                        pEchoChannel,
 
2461
                                                                                        ulAddress,
 
2462
                                                                                        &ulTempData,
 
2463
                                                                                        ulResult );
 
2464
                if ( ulResult != cOCT6100_ERR_OK )
 
2465
                        return ulResult;
 
2466
                
 
2467
                mOCT6100_CREATE_FEATURE_MASK( ulSkipPtrFieldSize, ulSkipPtrBitOfst, &ulMask );
 
2468
                
 
2469
                ulTempData &= ( ~ulMask );
 
2470
                ulTempData |= *pulSkipPtr << ulSkipPtrBitOfst;
 
2471
                
 
2472
                ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance,
 
2473
                                                                                pEchoChannel,
 
2474
                                                                                ulAddress,
 
2475
                                                                                ulTempData);
 
2476
                if ( ulResult != cOCT6100_ERR_OK )
 
2477
                        return ulResult;
 
2478
 
 
2479
                /*=======================================================================*/
 
2480
        }
 
2481
 
 
2482
 
 
2483
        /*=======================================================================*/
 
2484
        /* Fetch and modify the write pointer. */       
 
2485
 
 
2486
        ulAddress = ulPlayoutBaseAddress + ulWritePtrBytesOfst;
 
2487
 
 
2488
        mOCT6100_RETRIEVE_NLP_CONF_DWORD(       f_pApiInstance,
 
2489
                                                                                pEchoChannel,
 
2490
                                                                                ulAddress,
 
2491
                                                                                &ulTempData,
 
2492
                                                                                ulResult );
 
2493
        if ( ulResult != cOCT6100_ERR_OK )
 
2494
                return ulResult;
 
2495
        
 
2496
        mOCT6100_CREATE_FEATURE_MASK( ulWritePtrFieldSize, ulWritePtrBitOfst, &ulMask );
 
2497
        
 
2498
        ulTempData &= ( ~ulMask );
 
2499
        ulTempData |= ulWritePtr << ulWritePtrBitOfst;
 
2500
        
 
2501
        ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance,
 
2502
                                                                        pEchoChannel,
 
2503
                                                                        ulAddress,
 
2504
                                                                        ulTempData);
 
2505
        if ( ulResult != cOCT6100_ERR_OK )
 
2506
                return ulResult;
 
2507
        
 
2508
        /*=======================================================================*/
 
2509
        
 
2510
 
 
2511
        /*=======================================================================*/
 
2512
        /* Now update the state of the channel stating that the buffer playout is activated. */
 
2513
 
 
2514
        /* Select the buffer of interest.*/
 
2515
        if ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT )
 
2516
        {
 
2517
                /* Check if the global ports active stat must be incremented. */
 
2518
                if ( pEchoChannel->fRinBufPlaying == FALSE )
 
2519
                {
 
2520
                        /* Increment the number of active buffer playout ports. */
 
2521
                        pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts++;
 
2522
                }
 
2523
 
 
2524
                pEchoChannel->fRinBufPlaying = TRUE;
 
2525
                /* Keep the new notify on event flag. */
 
2526
                pEchoChannel->fRinBufPlayoutNotifyOnStop = (UINT8)( f_fNotifyOnPlayoutStop & 0xFF );
 
2527
                /* Keep the specified user event id. */
 
2528
                pEchoChannel->ulRinUserBufPlayoutEventId = f_ulUserEventId;
 
2529
                /* Keep type of event to be generated. */
 
2530
                pEchoChannel->byRinPlayoutStopEventType = (UINT8)( f_ulPlayoutStopEventType & 0xFF );
 
2531
                /* No hard stop for now. */
 
2532
                pEchoChannel->fRinHardStop = FALSE;
 
2533
                /* No buffer added in the rin list for now. */
 
2534
                pEchoChannel->fRinBufAdded = FALSE;
 
2535
                /* Buffer playout is active on this channel. */
 
2536
                pEchoChannel->fBufPlayoutActive = TRUE;
 
2537
        }
 
2538
        else /* f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */
 
2539
        {
 
2540
                /* Check if the global ports active stat must be incremented. */
 
2541
                if ( pEchoChannel->fSoutBufPlaying == FALSE )
 
2542
                {
 
2543
                        /* Increment the number of active buffer playout ports. */
 
2544
                        pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts++;
 
2545
                }
 
2546
 
 
2547
                pEchoChannel->fSoutBufPlaying = TRUE;
 
2548
                /* Keep the new notify on event flag. */
 
2549
                pEchoChannel->fSoutBufPlayoutNotifyOnStop = (UINT8)( f_fNotifyOnPlayoutStop & 0xFF );
 
2550
                /* Keep the specified user event id. */
 
2551
                pEchoChannel->ulSoutUserBufPlayoutEventId = f_ulUserEventId;
 
2552
                /* Keep type of event to be generated. */
 
2553
                pEchoChannel->bySoutPlayoutStopEventType = (UINT8)( f_ulPlayoutStopEventType & 0xFF );
 
2554
                /* No hard stop for now. */
 
2555
                pEchoChannel->fSoutHardStop = FALSE;
 
2556
                /* No buffer added in the sout list for now. */
 
2557
                pEchoChannel->fSoutBufAdded = FALSE;
 
2558
                /* Buffer playout is active on this channel. */
 
2559
                pEchoChannel->fBufPlayoutActive = TRUE;
 
2560
        }
 
2561
 
 
2562
        return cOCT6100_ERR_OK;
 
2563
}
 
2564
#endif
 
2565
 
 
2566
 
 
2567
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
2568
 
 
2569
Function:               Oct6100BufferPlayoutStopSer
 
2570
 
 
2571
Description:    Stops buffer playout on a channel.
 
2572
 
 
2573
-------------------------------------------------------------------------------
 
2574
|       Argument                |       Description
 
2575
-------------------------------------------------------------------------------
 
2576
f_pApiInstance                  Pointer to API instance. This memory is used to keep the
 
2577
                                                present state of the chip and all its resources.
 
2578
 
 
2579
f_pBufferPlayoutStop    Pointer to buffer playout stop structure.
 
2580
 
 
2581
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
2582
#if !SKIP_Oct6100BufferPlayoutStopSer
 
2583
UINT32 Oct6100BufferPlayoutStopSer(
 
2584
                                IN OUT  tPOCT6100_INSTANCE_API                          f_pApiInstance,
 
2585
                                IN OUT  tPOCT6100_BUFFER_PLAYOUT_STOP           f_pBufferPlayoutStop )
 
2586
{
 
2587
        UINT32  ulChannelIndex;
 
2588
        UINT16  usEchoMemIndex;
 
2589
        UINT32  ulResult;
 
2590
 
 
2591
        /* Check the user's configuration of the buffer for errors. */
 
2592
        ulResult = Oct6100ApiAssertPlayoutStopParams( 
 
2593
                                                                                                f_pApiInstance, 
 
2594
                                                                                                f_pBufferPlayoutStop, 
 
2595
                                                                                                &ulChannelIndex, 
 
2596
                                                                                                &usEchoMemIndex );
 
2597
        if ( ulResult != cOCT6100_ERR_OK )
 
2598
                return ulResult;
 
2599
 
 
2600
        /* Write to  all resources needed to deactivate buffer playout. */
 
2601
        ulResult = Oct6100ApiInvalidateChanPlayoutStructs( 
 
2602
                                                                                                f_pApiInstance, 
 
2603
                                                                                                f_pBufferPlayoutStop, 
 
2604
                                                                                                ulChannelIndex, 
 
2605
                                                                                                usEchoMemIndex 
 
2606
 
 
2607
                                                                                                );
 
2608
        if ( ulResult != cOCT6100_ERR_OK )
 
2609
                return ulResult;
 
2610
 
 
2611
        return cOCT6100_ERR_OK;
 
2612
}
 
2613
#endif
 
2614
 
 
2615
 
 
2616
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
2617
 
 
2618
Function:               Oct6100ApiAssertPlayoutStopParams
 
2619
 
 
2620
Description:    Check the validity of the channel and buffer requested.
 
2621
 
 
2622
-------------------------------------------------------------------------------
 
2623
|       Argument                |       Description
 
2624
-------------------------------------------------------------------------------
 
2625
f_pApiInstance                  Pointer to API instance. This memory is used to keep the
 
2626
                                                present state of the chip and all its resources.
 
2627
 
 
2628
f_pBufferPlayoutStop    Pointer to buffer playout stop structure.  
 
2629
f_pulChannelIndex               Pointer to the channel index on which playout is to be stopped.
 
2630
f_pusEchoMemIndex               Pointer to the echo mem index on which playout is to be stopped.
 
2631
 
 
2632
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
2633
#if !SKIP_Oct6100ApiAssertPlayoutStopParams
 
2634
UINT32 Oct6100ApiAssertPlayoutStopParams(
 
2635
                                IN OUT  tPOCT6100_INSTANCE_API                          f_pApiInstance,
 
2636
                                IN              tPOCT6100_BUFFER_PLAYOUT_STOP           f_pBufferPlayoutStop,
 
2637
                                OUT             PUINT32                                                         f_pulChannelIndex,
 
2638
                                OUT             PUINT16                                                         f_pusEchoMemIndex )
 
2639
{
 
2640
        tPOCT6100_API_CHANNEL           pEchoChannel;
 
2641
        UINT32  ulEntryOpenCnt;
 
2642
 
 
2643
        /* Check for errors. */
 
2644
        if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxPlayoutBuffers == 0 )
 
2645
                return cOCT6100_ERR_BUFFER_PLAYOUT_DISABLED;
 
2646
        
 
2647
        if ( f_pBufferPlayoutStop->ulChannelHndl == cOCT6100_INVALID_HANDLE )
 
2648
                return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID;
 
2649
 
 
2650
        if ( f_pBufferPlayoutStop->ulPlayoutPort != cOCT6100_CHANNEL_PORT_ROUT && 
 
2651
                 f_pBufferPlayoutStop->ulPlayoutPort != cOCT6100_CHANNEL_PORT_SOUT )
 
2652
                return cOCT6100_ERR_BUFFER_PLAYOUT_PLAYOUT_PORT;
 
2653
 
 
2654
        if ( f_pBufferPlayoutStop->fStopCleanly != TRUE && f_pBufferPlayoutStop->fStopCleanly != FALSE )
 
2655
                return cOCT6100_ERR_BUFFER_PLAYOUT_STOP_CLEANLY;
 
2656
        
 
2657
        /*=====================================================================*/
 
2658
        /* Check the channel handle. */
 
2659
 
 
2660
        if ( (f_pBufferPlayoutStop->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL )
 
2661
                return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID;
 
2662
 
 
2663
        *f_pulChannelIndex = f_pBufferPlayoutStop->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK;
 
2664
        if ( *f_pulChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels )
 
2665
                return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID;
 
2666
 
 
2667
        mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChannel, *f_pulChannelIndex )
 
2668
 
 
2669
        /* Extract the entry open count from the provided handle. */
 
2670
        ulEntryOpenCnt = (f_pBufferPlayoutStop->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK;
 
2671
 
 
2672
        /* Check for errors. */
 
2673
        if ( pEchoChannel->fReserved != TRUE )
 
2674
                return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_NOT_OPEN;
 
2675
        if ( ulEntryOpenCnt != pEchoChannel->byEntryOpenCnt )
 
2676
                return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID;
 
2677
 
 
2678
        /* Return echo memory index. */
 
2679
        *f_pusEchoMemIndex = pEchoChannel->usEchoMemIndex;
 
2680
 
 
2681
        /* Check if buffer playout is active for the selected port. */
 
2682
        if ( ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT )
 
2683
                && ( pEchoChannel->fRinBufPlaying == FALSE )
 
2684
                && ( pEchoChannel->fRinBufAdded == FALSE ) )
 
2685
                return cOCT6100_ERR_BUFFER_PLAYOUT_NOT_STARTED;
 
2686
 
 
2687
        if ( ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT )
 
2688
                && ( pEchoChannel->fSoutBufPlaying == FALSE )
 
2689
                 && ( pEchoChannel->fSoutBufAdded == FALSE ) )
 
2690
                return cOCT6100_ERR_BUFFER_PLAYOUT_NOT_STARTED;
 
2691
        
 
2692
        /*=====================================================================*/
 
2693
 
 
2694
        return cOCT6100_ERR_OK;
 
2695
}
 
2696
#endif
 
2697
 
 
2698
 
 
2699
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
2700
 
 
2701
Function:               Oct6100ApiInvalidateChanPlayoutStructs
 
2702
 
 
2703
Description:    Write the buffer playout event in the channel main structure.
 
2704
 
 
2705
-------------------------------------------------------------------------------
 
2706
|       Argument                |       Description
 
2707
-------------------------------------------------------------------------------
 
2708
f_pApiInstance                          Pointer to API instance. This memory is used to keep the
 
2709
                                                        present state of the chip and all its resources.
 
2710
        
 
2711
f_pBufferPlayoutStop            Pointer to buffer playout stop structure.  
 
2712
f_ulChannelIndex                        Index of the channel within the API's channel list.
 
2713
f_usEchoMemIndex                        Index of the echo channel in hardware memory.
 
2714
 
 
2715
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
2716
#if !SKIP_Oct6100ApiInvalidateChanPlayoutStructs
 
2717
UINT32 Oct6100ApiInvalidateChanPlayoutStructs(
 
2718
                                IN OUT  tPOCT6100_INSTANCE_API                          f_pApiInstance,
 
2719
                                IN              tPOCT6100_BUFFER_PLAYOUT_STOP           f_pBufferPlayoutStop,
 
2720
                                IN              UINT32                                                          f_ulChannelIndex,
 
2721
                                IN              UINT16                                                          f_usEchoMemIndex
 
2722
 
 
2723
                                )
 
2724
{
 
2725
        tPOCT6100_API_CHANNEL   pEchoChannel;
 
2726
        tPOCT6100_SHARED_INFO   pSharedInfo;
 
2727
        tOCT6100_READ_PARAMS    ReadParams;
 
2728
        tOCT6100_WRITE_PARAMS   WriteParams;
 
2729
 
 
2730
        UINT32  ulResult;
 
2731
 
 
2732
        UINT32  ulWritePtrBytesOfst;
 
2733
        UINT32  ulWritePtrBitOfst;
 
2734
        UINT32  ulWritePtrFieldSize;
 
2735
        UINT32  ulSkipPtrBytesOfst;
 
2736
        UINT32  ulSkipPtrBitOfst;
 
2737
        UINT32  ulSkipPtrFieldSize;
 
2738
        UINT32  ulIgnoreBytesOfst;
 
2739
        UINT32  ulIgnoreBitOfst;
 
2740
        UINT32  ulIgnoreFieldSize;
 
2741
        UINT32  ulHardSkipBytesOfst;
 
2742
        UINT32  ulHardSkipBitOfst;
 
2743
        UINT32  ulHardSkipFieldSize;
 
2744
        UINT32  ulReadPtrBytesOfst;
 
2745
        UINT32  ulReadPtrBitOfst;
 
2746
        UINT32  ulReadPtrFieldSize;
 
2747
 
 
2748
        UINT32  ulSkipPtr;
 
2749
        UINT32  ulWritePtr;
 
2750
        UINT32  ulReadPtr = 0;
 
2751
        UINT32  ulCurrentPtr;
 
2752
 
 
2753
        UINT32  ulPlayoutBaseAddress;
 
2754
        UINT32  ulAddress;
 
2755
        UINT32  ulTempData;
 
2756
        UINT32  ulMask;
 
2757
        UINT32  ulReadData;
 
2758
 
 
2759
        UINT16  usReadData;     
 
2760
        BOOL    fCheckStop = FALSE;
 
2761
 
 
2762
        UINT32  ulEventBuffer;
 
2763
 
 
2764
        /* Obtain local pointer to shared portion of instance. */
 
2765
        pSharedInfo = f_pApiInstance->pSharedInfo;
 
2766
 
 
2767
        WriteParams.pProcessContext = f_pApiInstance->pProcessContext;
 
2768
 
 
2769
        WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId;
 
2770
 
 
2771
        ReadParams.pProcessContext = f_pApiInstance->pProcessContext;
 
2772
 
 
2773
        ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
 
2774
        ReadParams.pusReadData = &usReadData;
 
2775
 
 
2776
        mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChannel, f_ulChannelIndex );
 
2777
 
 
2778
        /* Select the port of interest. */
 
2779
        if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT )
 
2780
        {
 
2781
                ulWritePtr = pEchoChannel->ulRinBufWritePtr; 
 
2782
                ulSkipPtr  = ulWritePtr;
 
2783
 
 
2784
                ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.usDwordOffset * 4;
 
2785
                ulWritePtrBitOfst       = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byBitOffset;
 
2786
                ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byFieldSize;
 
2787
 
 
2788
                ulSkipPtrBytesOfst  = pSharedInfo->MemoryMap.PlayoutRinSkipPtrOfst.usDwordOffset * 4;
 
2789
                ulSkipPtrBitOfst        = pSharedInfo->MemoryMap.PlayoutRinSkipPtrOfst.byBitOffset;
 
2790
                ulSkipPtrFieldSize      = pSharedInfo->MemoryMap.PlayoutRinSkipPtrOfst.byFieldSize;
 
2791
 
 
2792
                ulIgnoreBytesOfst       = pSharedInfo->MemoryMap.PlayoutRinIgnoreSkipCleanOfst.usDwordOffset * 4;
 
2793
                ulIgnoreBitOfst         = pSharedInfo->MemoryMap.PlayoutRinIgnoreSkipCleanOfst.byBitOffset;
 
2794
                ulIgnoreFieldSize       = pSharedInfo->MemoryMap.PlayoutRinIgnoreSkipCleanOfst.byFieldSize;
 
2795
 
 
2796
                ulHardSkipBytesOfst     = pSharedInfo->MemoryMap.PlayoutRinHardSkipOfst.usDwordOffset * 4;
 
2797
                ulHardSkipBitOfst       = pSharedInfo->MemoryMap.PlayoutRinHardSkipOfst.byBitOffset;
 
2798
                ulHardSkipFieldSize     = pSharedInfo->MemoryMap.PlayoutRinHardSkipOfst.byFieldSize;
 
2799
 
 
2800
                ulReadPtrBytesOfst      = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.usDwordOffset * 4;
 
2801
                ulReadPtrBitOfst        = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byBitOffset;
 
2802
                ulReadPtrFieldSize      = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byFieldSize;
 
2803
        }
 
2804
        else /* f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */
 
2805
        {
 
2806
                ulWritePtr = pEchoChannel->ulSoutBufWritePtr; 
 
2807
                ulSkipPtr  = ulWritePtr;
 
2808
 
 
2809
                ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.usDwordOffset * 4;
 
2810
                ulWritePtrBitOfst       = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byBitOffset;
 
2811
                ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byFieldSize;
 
2812
 
 
2813
                ulSkipPtrBytesOfst  = pSharedInfo->MemoryMap.PlayoutSoutSkipPtrOfst.usDwordOffset * 4;
 
2814
                ulSkipPtrBitOfst        = pSharedInfo->MemoryMap.PlayoutSoutSkipPtrOfst.byBitOffset;
 
2815
                ulSkipPtrFieldSize      = pSharedInfo->MemoryMap.PlayoutSoutSkipPtrOfst.byFieldSize;
 
2816
 
 
2817
                ulIgnoreBytesOfst       = pSharedInfo->MemoryMap.PlayoutSoutIgnoreSkipCleanOfst.usDwordOffset * 4;
 
2818
                ulIgnoreBitOfst         = pSharedInfo->MemoryMap.PlayoutSoutIgnoreSkipCleanOfst.byBitOffset;
 
2819
                ulIgnoreFieldSize       = pSharedInfo->MemoryMap.PlayoutSoutIgnoreSkipCleanOfst.byFieldSize;
 
2820
 
 
2821
                ulHardSkipBytesOfst     = pSharedInfo->MemoryMap.PlayoutSoutHardSkipOfst.usDwordOffset * 4;
 
2822
                ulHardSkipBitOfst       = pSharedInfo->MemoryMap.PlayoutSoutHardSkipOfst.byBitOffset;
 
2823
                ulHardSkipFieldSize     = pSharedInfo->MemoryMap.PlayoutSoutHardSkipOfst.byFieldSize;
 
2824
 
 
2825
                ulReadPtrBytesOfst      = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.usDwordOffset * 4;
 
2826
                ulReadPtrBitOfst        = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byBitOffset;
 
2827
                ulReadPtrFieldSize      = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byFieldSize;
 
2828
        }
 
2829
 
 
2830
        /* Set the playout feature base address. */
 
2831
        ulPlayoutBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst;
 
2832
 
 
2833
        /* Check if something is currently playing. */
 
2834
        if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT )
 
2835
        {
 
2836
                if ( pEchoChannel->fRinBufPlaying == TRUE )
 
2837
                {
 
2838
                        /* Check if we are stopping it or if it stopped by itself. */
 
2839
                        fCheckStop = TRUE;
 
2840
                }
 
2841
                else
 
2842
                {
 
2843
                        /* Not playing! */
 
2844
                        if ( f_pBufferPlayoutStop->pfAlreadyStopped != NULL )
 
2845
                                *f_pBufferPlayoutStop->pfAlreadyStopped = TRUE;
 
2846
                }
 
2847
        }
 
2848
        else /* if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) */
 
2849
        {
 
2850
                if ( pEchoChannel->fSoutBufPlaying == TRUE )
 
2851
                {
 
2852
                        /* Check if we are stopping it or if it stopped by itself. */
 
2853
                        fCheckStop = TRUE;
 
2854
                }
 
2855
                else
 
2856
                {
 
2857
                        /* Not playing! */
 
2858
                        if ( f_pBufferPlayoutStop->pfAlreadyStopped != NULL )
 
2859
                                *f_pBufferPlayoutStop->pfAlreadyStopped = TRUE;
 
2860
                }
 
2861
        }
 
2862
 
 
2863
        if ( ( fCheckStop == TRUE ) || ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == TRUE ) )
 
2864
        {
 
2865
                /* Read the read pointer. */
 
2866
                ReadParams.pProcessContext = f_pApiInstance->pProcessContext;
 
2867
 
 
2868
                ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
 
2869
                ReadParams.pusReadData = &usReadData;
 
2870
                ReadParams.ulReadAddress = ulPlayoutBaseAddress + ulReadPtrBytesOfst;
 
2871
 
 
2872
                /* Optimize this access by only reading the word we are interested in. */
 
2873
                if ( ulReadPtrBitOfst < 16 )
 
2874
                        ReadParams.ulReadAddress += 2;
 
2875
 
 
2876
                /* Must read in memory directly since this value is changed by hardware */
 
2877
                mOCT6100_DRIVER_READ_API( ReadParams, ulResult )
 
2878
                if ( ulResult != cOCT6100_ERR_OK )
 
2879
                        return ulResult;
 
2880
 
 
2881
                /* Move data at correct position according to what was read. */
 
2882
                if ( ulReadPtrBitOfst < 16 )
 
2883
                        ulTempData = usReadData;
 
2884
                else
 
2885
                        ulTempData = usReadData << 16;
 
2886
                
 
2887
                mOCT6100_CREATE_FEATURE_MASK( ulReadPtrFieldSize, ulReadPtrBitOfst, &ulMask );
 
2888
                
 
2889
                /* Store the read pointer. */
 
2890
                ulReadPtr = ( ulTempData & ulMask ) >> ulReadPtrBitOfst;
 
2891
 
 
2892
                /* Playout has finished when the read pointer reaches the write pointer. */
 
2893
                if ( f_pBufferPlayoutStop->pfAlreadyStopped != NULL )
 
2894
                {
 
2895
                        if ( ulReadPtr != ulWritePtr )
 
2896
                                *f_pBufferPlayoutStop->pfAlreadyStopped = FALSE;
 
2897
                        else /* if ( ulReadPtr == ulWritePtr ) */
 
2898
                                *f_pBufferPlayoutStop->pfAlreadyStopped = TRUE;
 
2899
                }
 
2900
        }
 
2901
 
 
2902
        /* If the skip bits are located in the event itself, the playout is stopped by setting the */
 
2903
        /* skip pointer to the hardware chip write pointer.  Read it directly from the NLP configuration. */
 
2904
        if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == TRUE )
 
2905
        {
 
2906
                if ( ulReadPtr != ulWritePtr )
 
2907
                {
 
2908
                        /* Get the write pointer in the chip. */
 
2909
                        ulAddress = ulPlayoutBaseAddress + ulWritePtrBytesOfst;
 
2910
 
 
2911
                        ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, pEchoChannel, ulAddress, &ulReadData);
 
2912
                        if ( ulResult != cOCT6100_ERR_OK )
 
2913
                                return ulResult;
 
2914
 
 
2915
                        mOCT6100_CREATE_FEATURE_MASK( ulWritePtrFieldSize, ulWritePtrBitOfst, &ulMask );
 
2916
 
 
2917
                        /* Store the write pointer. */
 
2918
                        ulWritePtr = ( ulReadData & ulMask ) >> ulWritePtrBitOfst;
 
2919
                        ulSkipPtr = ulWritePtr;
 
2920
                }
 
2921
        }
 
2922
 
 
2923
        /* Check if must clear repeat bit. */
 
2924
        if ( ( ( pEchoChannel->fRinBufPlayoutRepeatUsed == TRUE ) && ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) )
 
2925
                || ( ( pEchoChannel->fSoutBufPlayoutRepeatUsed == TRUE ) && ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) ) )
 
2926
        {
 
2927
                if ( ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == FALSE )
 
2928
                        || ( ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == TRUE )
 
2929
                                && ( ulWritePtr != ulReadPtr ) ) )
 
2930
                {
 
2931
                        if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT )
 
2932
                        {
 
2933
                                ulEventBuffer = pSharedInfo->MemoryMap.ulChanMainRinPlayoutMemOfst;
 
2934
                        }
 
2935
                        else /* f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */
 
2936
                        {
 
2937
                                ulEventBuffer = pSharedInfo->MemoryMap.ulChanMainSoutPlayoutMemOfst;
 
2938
                        }
 
2939
 
 
2940
                        /* Set the playout event base address. */
 
2941
                        if ( ( pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip == TRUE )
 
2942
                                && ( pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip == TRUE ) )
 
2943
                        {
 
2944
                                /* 127 or 31 events image. */
 
2945
                                ulAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoMemIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + ulEventBuffer + (cOCT6100_PLAYOUT_EVENT_MEM_SIZE * ( ( ulWritePtr - 1 ) & ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - 1 )));
 
2946
                        }
 
2947
                        else
 
2948
                        {
 
2949
                                /* Old 31 events image. */
 
2950
                                ulAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoMemIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + ulEventBuffer + (cOCT6100_PLAYOUT_EVENT_MEM_SIZE * ( ( ulWritePtr - 1 ) & 0x1F));
 
2951
                        }
 
2952
 
 
2953
                        /* EVENT BASE + 4 */
 
2954
                        /* Playout configuration. */
 
2955
                        ulAddress += 4;
 
2956
 
 
2957
                        ReadParams.ulReadAddress = ulAddress;
 
2958
                        mOCT6100_DRIVER_READ_API( ReadParams, ulResult );
 
2959
                        if ( ulResult != cOCT6100_ERR_OK )
 
2960
                                return ulResult;
 
2961
 
 
2962
                        /* Read-clear-write the new repeat bit. */
 
2963
                        usReadData &= 0x7FFF;
 
2964
 
 
2965
                        WriteParams.ulWriteAddress = ulAddress;
 
2966
                        WriteParams.usWriteData = usReadData;
 
2967
                        mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult );
 
2968
                        if ( ulResult != cOCT6100_ERR_OK )
 
2969
                                return ulResult;
 
2970
                }
 
2971
        }
 
2972
 
 
2973
        /* Write the skip to the value of the write pointer to stop buffer playout. */
 
2974
 
 
2975
        /*=======================================================================*/
 
2976
        /* First set the ignore skip clean bit if required. */  
 
2977
 
 
2978
        if ( ( pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip == FALSE )
 
2979
                || ( pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip == FALSE ) )
 
2980
        {
 
2981
                ulAddress = ulPlayoutBaseAddress + ulIgnoreBytesOfst;
 
2982
 
 
2983
                ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance,
 
2984
                                                                                        pEchoChannel,
 
2985
                                                                                        ulAddress,
 
2986
                                                                                        &ulTempData);
 
2987
                if ( ulResult != cOCT6100_ERR_OK )
 
2988
                        return ulResult;
 
2989
                
 
2990
                mOCT6100_CREATE_FEATURE_MASK( ulIgnoreFieldSize, ulIgnoreBitOfst, &ulMask );
 
2991
                
 
2992
                ulTempData &= ( ~ulMask );
 
2993
 
 
2994
                /* Check if the skip need to be clean or not. */
 
2995
                if ( f_pBufferPlayoutStop->fStopCleanly == FALSE )
 
2996
                        ulTempData |= 0x1 << ulIgnoreBitOfst;
 
2997
                
 
2998
                ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance,
 
2999
                                                                                pEchoChannel,
 
3000
                                                                                ulAddress,
 
3001
                                                                                ulTempData);
 
3002
                if ( ulResult != cOCT6100_ERR_OK )
 
3003
                        return ulResult;
 
3004
        }
 
3005
 
 
3006
        /*=======================================================================*/
 
3007
 
 
3008
        
 
3009
        /*=======================================================================*/
 
3010
        /* Fetch and modify the write pointer. */       
 
3011
 
 
3012
        ulAddress = ulPlayoutBaseAddress + ulWritePtrBytesOfst;
 
3013
 
 
3014
        ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, pEchoChannel, ulAddress, &ulTempData);
 
3015
        if ( ulResult != cOCT6100_ERR_OK )
 
3016
                return ulResult;
 
3017
        
 
3018
        mOCT6100_CREATE_FEATURE_MASK( ulWritePtrFieldSize, ulWritePtrBitOfst, &ulMask );
 
3019
        
 
3020
        ulTempData &= ( ~ulMask );
 
3021
        ulTempData |= ulWritePtr << ulWritePtrBitOfst;
 
3022
        
 
3023
        ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance,
 
3024
                                                                        pEchoChannel,
 
3025
                                                                        ulAddress,
 
3026
                                                                        ulTempData);
 
3027
        if ( ulResult != cOCT6100_ERR_OK )
 
3028
                return ulResult;
 
3029
        
 
3030
        /*=======================================================================*/
 
3031
 
 
3032
        
 
3033
        /*=======================================================================*/
 
3034
        /* Fetch and modify the skip pointer. */        
 
3035
 
 
3036
        ulAddress = ulPlayoutBaseAddress + ulSkipPtrBytesOfst;
 
3037
 
 
3038
        ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance,
 
3039
                                                                                pEchoChannel,
 
3040
                                                                                ulAddress,
 
3041
                                                                                &ulTempData);
 
3042
        if ( ulResult != cOCT6100_ERR_OK )
 
3043
                return ulResult;
 
3044
        
 
3045
        mOCT6100_CREATE_FEATURE_MASK( ulSkipPtrFieldSize, ulSkipPtrBitOfst, &ulMask );
 
3046
        
 
3047
        ulTempData &= ( ~ulMask );
 
3048
        ulTempData |= ulSkipPtr << ulSkipPtrBitOfst;
 
3049
        
 
3050
        ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance,
 
3051
                                                                        pEchoChannel,
 
3052
                                                                        ulAddress,
 
3053
                                                                        ulTempData);
 
3054
        if ( ulResult != cOCT6100_ERR_OK )
 
3055
                return ulResult;
 
3056
        
 
3057
        /*=======================================================================*/
 
3058
        
 
3059
 
 
3060
        /*=======================================================================*/
 
3061
        /* If in the new buffer playout case, things are in a different order. */       
 
3062
 
 
3063
        if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == FALSE )
 
3064
        {
 
3065
                if ( ( pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip == TRUE )
 
3066
                        && ( pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip == TRUE ) )
 
3067
                {
 
3068
                        ulAddress = ulPlayoutBaseAddress + ulHardSkipBytesOfst;
 
3069
 
 
3070
                        ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance,
 
3071
                                                                                                pEchoChannel,
 
3072
                                                                                                ulAddress,
 
3073
                                                                                                &ulTempData);
 
3074
                        if ( ulResult != cOCT6100_ERR_OK )
 
3075
                                return ulResult;
 
3076
                        
 
3077
                        mOCT6100_CREATE_FEATURE_MASK( ulHardSkipFieldSize, ulHardSkipBitOfst, &ulMask );
 
3078
                        
 
3079
                        ulTempData &= ( ~ulMask );
 
3080
 
 
3081
                        /* Check if the skip need to be clean or not. */
 
3082
                        if ( f_pBufferPlayoutStop->fStopCleanly == FALSE )
 
3083
                                ulTempData |= 0x1 << ulHardSkipBitOfst;
 
3084
                        
 
3085
                        ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance,
 
3086
                                                                                        pEchoChannel,
 
3087
                                                                                        ulAddress,
 
3088
                                                                                        ulTempData);
 
3089
                        if ( ulResult != cOCT6100_ERR_OK )
 
3090
                                return ulResult;
 
3091
 
 
3092
                        /* Now is the appropriate time to skip! */
 
3093
                        ulAddress = ulPlayoutBaseAddress + ulIgnoreBytesOfst;
 
3094
 
 
3095
                        ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance,
 
3096
                                                                                                pEchoChannel,
 
3097
                                                                                                ulAddress,
 
3098
                                                                                                &ulTempData);
 
3099
                        if ( ulResult != cOCT6100_ERR_OK )
 
3100
                                return ulResult;
 
3101
                        
 
3102
                        mOCT6100_CREATE_FEATURE_MASK( ulIgnoreFieldSize, ulIgnoreBitOfst, &ulMask );
 
3103
 
 
3104
                        ulTempData &= ( ~ulMask );
 
3105
 
 
3106
                        /* Set the skip bit. */
 
3107
                        ulTempData |= 0x1 << ulIgnoreBitOfst;
 
3108
                        
 
3109
                        ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance,
 
3110
                                                                                        pEchoChannel,
 
3111
                                                                                        ulAddress,
 
3112
                                                                                        ulTempData);
 
3113
                        if ( ulResult != cOCT6100_ERR_OK )
 
3114
                                return ulResult;
 
3115
                }
 
3116
        }
 
3117
 
 
3118
        /*=======================================================================*/
 
3119
 
 
3120
 
 
3121
        /*=======================================================================*/
 
3122
        /* The API must set the skip bit in all the events that are queued. */
 
3123
 
 
3124
        if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == TRUE )
 
3125
        {
 
3126
                if ( fCheckStop == TRUE )
 
3127
                {
 
3128
                        if ( ulReadPtr != ulWritePtr )
 
3129
                        {
 
3130
                                if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT )
 
3131
                                {
 
3132
                                        ulEventBuffer = pSharedInfo->MemoryMap.ulChanMainRinPlayoutMemOfst;
 
3133
                                }
 
3134
                                else /* f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */
 
3135
                                {
 
3136
                                        ulEventBuffer = pSharedInfo->MemoryMap.ulChanMainSoutPlayoutMemOfst;
 
3137
                                }
 
3138
 
 
3139
                                for ( ulCurrentPtr = ulReadPtr; ulCurrentPtr != ulWritePtr; )
 
3140
                                {
 
3141
                                        /* Set the playout event base address. */
 
3142
                                        
 
3143
                                        /* 127 or 31 events image. */
 
3144
                                        ulAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoMemIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + ulEventBuffer + ( cOCT6100_PLAYOUT_EVENT_MEM_SIZE * ulCurrentPtr );
 
3145
                                        ulCurrentPtr++;
 
3146
                                        ulCurrentPtr &= ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - 1 );
 
3147
 
 
3148
                                        /* EVENT BASE + 0 playout configuration. */
 
3149
                                        WriteParams.ulWriteAddress = ulAddress;
 
3150
 
 
3151
                                        /* Set skip bit + hard-skip bit. */
 
3152
                                        WriteParams.usWriteData = 0x8000;
 
3153
                                        if ( f_pBufferPlayoutStop->fStopCleanly == FALSE )
 
3154
                                                WriteParams.usWriteData |= 0x4000;
 
3155
                                        mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult );
 
3156
                                        if ( ulResult != cOCT6100_ERR_OK )
 
3157
                                                return ulResult;
 
3158
                                }
 
3159
                        }
 
3160
                }
 
3161
        }
 
3162
 
 
3163
        /*=======================================================================*/
 
3164
        /* If stop immediatly, wait the stop before leaving the function. */
 
3165
 
 
3166
        if ( f_pBufferPlayoutStop->fStopCleanly == FALSE )
 
3167
        {
 
3168
                /* Remember that an "hard stop" was used for the next start. */
 
3169
                if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT )
 
3170
                        pEchoChannel->fRinHardStop = TRUE;
 
3171
                else /* if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) */
 
3172
                        pEchoChannel->fSoutHardStop = TRUE;
 
3173
        }
 
3174
 
 
3175
        /*=======================================================================*/
 
3176
        /* Update the channel entry to set the playing flag to FALSE. */
 
3177
 
 
3178
        /* Select the port of interest. */
 
3179
        if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT )
 
3180
        {
 
3181
                /* Check if the global ports active stat must be decremented. */
 
3182
                if ( pEchoChannel->fRinBufPlaying == TRUE )
 
3183
                {
 
3184
                        /* Decrement the number of active buffer playout ports. */
 
3185
                        pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts--;
 
3186
                }
 
3187
 
 
3188
                pEchoChannel->fRinBufPlaying = FALSE;
 
3189
 
 
3190
                /* Return user information. */
 
3191
                if ( f_pBufferPlayoutStop->pfNotifyOnPlayoutStop != NULL )
 
3192
                        *f_pBufferPlayoutStop->pfNotifyOnPlayoutStop = pEchoChannel->fRinBufPlayoutNotifyOnStop;
 
3193
 
 
3194
                /* Make sure no new event is recorded for this channel/port. */
 
3195
                pEchoChannel->fRinBufPlayoutNotifyOnStop = FALSE;
 
3196
                if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == TRUE )
 
3197
                {
 
3198
                        pEchoChannel->ulRinBufSkipPtr = ulSkipPtr;
 
3199
                        pEchoChannel->ulRinBufWritePtr = ulWritePtr;
 
3200
                }
 
3201
                else /* if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == FALSE ) */
 
3202
                        pEchoChannel->ulRinBufSkipPtr = pEchoChannel->ulRinBufWritePtr;
 
3203
 
 
3204
                /* The repeat flag can now be used. */
 
3205
                pEchoChannel->fRinBufPlayoutRepeatUsed = FALSE;
 
3206
 
 
3207
                /* For sure, all buffers have now been cleared on the Rin port. */
 
3208
                pEchoChannel->fRinBufAdded = FALSE;
 
3209
 
 
3210
                /* Clear optimization flag if possible. */
 
3211
                if ( ( pEchoChannel->fSoutBufPlaying == FALSE )
 
3212
                        && ( pEchoChannel->fSoutBufPlayoutNotifyOnStop == FALSE ) )
 
3213
                {
 
3214
                        /* Buffer playout is no more active on this channel. */
 
3215
                        pEchoChannel->fBufPlayoutActive = FALSE;
 
3216
                }
 
3217
        }
 
3218
        else /* f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */
 
3219
        {
 
3220
                /* Check if the global ports active stat must be decremented. */
 
3221
                if ( pEchoChannel->fSoutBufPlaying == TRUE )
 
3222
                {
 
3223
                        /* Decrement the number of active buffer playout ports. */
 
3224
                        pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts--;
 
3225
                }
 
3226
 
 
3227
                pEchoChannel->fSoutBufPlaying = FALSE;
 
3228
 
 
3229
                /* Return user information. */
 
3230
                if ( f_pBufferPlayoutStop->pfNotifyOnPlayoutStop != NULL )
 
3231
                        *f_pBufferPlayoutStop->pfNotifyOnPlayoutStop = pEchoChannel->fSoutBufPlayoutNotifyOnStop;
 
3232
 
 
3233
                /* Make sure no new event is recorded for this channel/port. */
 
3234
                pEchoChannel->fSoutBufPlayoutNotifyOnStop = FALSE;
 
3235
                if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == TRUE )
 
3236
                {
 
3237
                        pEchoChannel->ulSoutBufSkipPtr = ulSkipPtr;
 
3238
                        pEchoChannel->ulSoutBufWritePtr = ulWritePtr;
 
3239
                }
 
3240
                else /* if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == FALSE ) */
 
3241
                        pEchoChannel->ulSoutBufSkipPtr = pEchoChannel->ulSoutBufWritePtr;
 
3242
 
 
3243
                /* The repeat flag can now be used. */
 
3244
                pEchoChannel->fSoutBufPlayoutRepeatUsed = FALSE;
 
3245
 
 
3246
                /* For sure, all buffers have now been cleared on the Sout port. */
 
3247
                pEchoChannel->fSoutBufAdded = FALSE;
 
3248
 
 
3249
                /* Clear optimization flag if possible. */
 
3250
                if ( ( pEchoChannel->fRinBufPlaying == FALSE )
 
3251
                        && ( pEchoChannel->fRinBufPlayoutNotifyOnStop == FALSE ) )
 
3252
                {
 
3253
                        /* Buffer playout is no more active on this channel. */
 
3254
                        pEchoChannel->fBufPlayoutActive = FALSE;
 
3255
                }
 
3256
        }
 
3257
 
 
3258
        /*=======================================================================*/
 
3259
 
 
3260
 
 
3261
 
 
3262
        return cOCT6100_ERR_OK;
 
3263
}
 
3264
#endif
 
3265
 
 
3266
 
 
3267
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
3268
 
 
3269
Function:               Oct6100ApiReserveBufPlayoutListEntry
 
3270
 
 
3271
Description:    Reserves a free entry in the Buffer playout list.
 
3272
 
 
3273
-------------------------------------------------------------------------------
 
3274
|       Argument                |       Description
 
3275
-------------------------------------------------------------------------------
 
3276
f_pApiInstance                  Pointer to API instance. This memory is used to keep the
 
3277
                                                present state of the chip and all its resources.
 
3278
 
 
3279
f_pulBufferIndex                List entry reserved.
 
3280
 
 
3281
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
3282
#if !SKIP_Oct6100ApiReserveBufPlayoutListEntry
 
3283
UINT32 Oct6100ApiReserveBufPlayoutListEntry(
 
3284
                                IN OUT  tPOCT6100_INSTANCE_API                  f_pApiInstance,
 
3285
                                OUT             PUINT32                                                 f_pulBufferIndex )
 
3286
{
 
3287
        PVOID   pBufPlayoutAlloc;
 
3288
        UINT32  ulResult;
 
3289
 
 
3290
        mOCT6100_GET_BUFFER_ALLOC_PNT( f_pApiInstance->pSharedInfo, pBufPlayoutAlloc )
 
3291
 
 
3292
        ulResult = OctapiLlmAllocAlloc( pBufPlayoutAlloc, f_pulBufferIndex );
 
3293
        if ( ulResult != cOCT6100_ERR_OK )
 
3294
        {
 
3295
                if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT )
 
3296
                        return cOCT6100_ERR_BUFFER_PLAYOUT_ALL_BUFFERS_OPEN;
 
3297
                else
 
3298
                        return cOCT6100_ERR_FATAL_40;
 
3299
        }
 
3300
 
 
3301
        return cOCT6100_ERR_OK;
 
3302
}
 
3303
#endif
 
3304
 
 
3305
 
 
3306
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
3307
 
 
3308
Function:               Oct6100ApiReleaseBufPlayoutListEntry
 
3309
 
 
3310
Description:    Release an entry from the Buffer playout list.
 
3311
 
 
3312
-------------------------------------------------------------------------------
 
3313
|       Argument                |       Description
 
3314
-------------------------------------------------------------------------------
 
3315
f_pApiInstance                  Pointer to API instance. This memory is used to keep the
 
3316
                                                present state of the chip and all its resources.
 
3317
 
 
3318
f_ulBufferIndex                 List entry to be freed.
 
3319
 
 
3320
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
3321
#if !SKIP_Oct6100ApiReleaseBufPlayoutListEntry
 
3322
UINT32 Oct6100ApiReleaseBufPlayoutListEntry(
 
3323
                                IN OUT  tPOCT6100_INSTANCE_API                  f_pApiInstance,
 
3324
                                IN              UINT32                                                  f_ulBufferIndex )
 
3325
{
 
3326
        PVOID   pBufPlayoutAlloc;
 
3327
        UINT32  ulResult;
 
3328
 
 
3329
        mOCT6100_GET_BUFFER_ALLOC_PNT( f_pApiInstance->pSharedInfo, pBufPlayoutAlloc )
 
3330
 
 
3331
        ulResult = OctapiLlmAllocDealloc( pBufPlayoutAlloc, f_ulBufferIndex );
 
3332
        if ( ulResult != cOCT6100_ERR_OK )
 
3333
                return cOCT6100_ERR_FATAL_41;
 
3334
 
 
3335
        return cOCT6100_ERR_OK;
 
3336
}
 
3337
#endif