Ignore:
Timestamp:
Nov 19, 2007, 7:04:04 AM (18 years ago)
Author:
Brendan Oakley
Message:

Load of work from Pavel to improve HDA in Uniaud32

File:
1 edited

Legend:

Unmodified
Added
Removed
  • GPL/trunk/lib32/sound.c

    r267 r269  
    5252int pcm_device = 0;
    5353int total = 0;
    54 int pcm_instances = 0;
     54// int pcm_instances = 0;  //PS+++ !!!!!!! what is it!!!! see pcm.lib
    5555
    5656OpenedHandles opened_handles[8 * 256] = {0};
     
    10651065
    10661066//******************************************************************************
     1067ULONG CountWv=0;
     1068ULONG LockAdd=0;
     1069extern  ULONG xchg( ULONG *p, ULONG x);
     1070#pragma aux xchg = "xchg [esi],eax" parm [ESI][EAX] value [EAX];
    10671071//******************************************************************************
    10681072OSSRET OSS32_WaveAddBuffer(OSSSTREAMID streamid, ULONG buffer, ULONG size, ULONG *pTransferred, int pcm)
     
    10721076    int                 ret, align, size1, ret1;
    10731077    LONG                transferred;
    1074     ULONG               position,i;
     1078    ULONG               position,i,j;
    10751079    char                *buf;
    1076     int toret = 0;
    10771080
    10781081//    return OSSERR_SUCCESS;
     
    11031106
    11041107    size = min(size, samples_to_bytes(status.avail));
     1108
     1109#ifdef DEBUG_PK
    11051110    if (size1 != size)
    1106         printk("requested size [%i] less then available [%i]\n", size1, size);
    1107 #if 0
    1108     if (size < per_bytes)
    1109     { /*HACK!!!*/
    1110         printk("HACK avoid buffer overrun: requested buffer [%i] less than period [%i]. prev size: %i\n", size, per_bytes, prev_size);
    1111         *pTransferred = size;
    1112         prev_size = size;
    1113         ret1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0);
    1114         return OSSERR_SUCCESS;
    1115     }
     1111        printk("requested size [%d] less then available [%d]\n", size1, size);
    11161112#endif
    1117 //    size = per_bytes * (size / per_bytes);
    1118 
    1119 #ifdef DEBUG_PK
    1120     printk("OSS32_WaveAddBuffer hw %i app %i avail %i, orig size: %i, size %i align %i\n", samples_to_bytes(status.hw_ptr), samples_to_bytes(status.appl_ptr), samples_to_bytes(status.avail), size1, size, per_bytes);
     1113
     1114    CountWv++;
     1115
     1116#ifdef DEBUG
     1117    printk("OSS32_WaveAddBuffer N:%d hw %d app %d avail %d, orig size: %d, size %d\n",CountWv, samples_to_bytes(status.hw_ptr), samples_to_bytes(status.appl_ptr), samples_to_bytes(status.avail), size1, size);
    11211118#endif
    11221119
    1123     if(size == 0) {
     1120    if (size == 0)
     1121    {
    11241122#ifdef DEBUG_PK
    11251123        printk("OSS32_WaveAddBuffer: no room left in hardware buffer!!\n");
     
    11331131
    11341132    transferred = 0;
     1133    *pTransferred = 0;
     1134    ret = -11;
    11351135    switch(SNDRV_MINOR_DEVICE(MINOR(pHandle->inode.i_rdev-pcm)))
    11361136    {
    11371137    case SNDRV_MINOR_PCM_PLAYBACK:
    1138         // size should be aligned to channels number * samplesize
    1139 
    1140         while(TRUE) {
    1141         again:
    1142             for ( i=0; i < 10000; i++)
    1143             {
    1144             ret1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)__Stack32ToFlat(&status));
    1145             if ( status.state != SNDRV_PCM_STATE_XRUN ) break;
    1146             }
    1147             if ( i > 9998 )
    1148             {
    1149                 printk("timeout stat %x avail:%i:%i \n",status.state,samples_to_bytes(status.avail),status.avail);
    1150                 ret1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0);
    1151                 ret1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)__Stack32ToFlat(&status));
    1152             }
    1153             ret = pHandle->file.f_op->write(&pHandle->file, (char *)buffer, size, &pHandle->file.f_pos);
    1154             if(ret < 0) {
    1155                 // check EAGAIN
    1156                 if (ret == -EPIPE)
    1157                 {
    1158                     ret1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0);
    1159 //                    if (ret1 == 0) continue;
    1160 //                    printk("prepare rc %i\n",ret);
    1161                 }
    1162 
    1163                 if(transferred > 0) {
    1164                     printk("OSS32_WaveAddBuffer failed on partial transfer %x %i; ret = %i\n", buffer, size, ret);
    1165                     *pTransferred = transferred;
    1166                     if (toret > 4)
    1167                         return OSSERR_SUCCESS; /* avoid infinite loop */
    1168                     toret++;
    1169                     goto again;
    1170                 }
    1171 
    1172                 ret1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)__Stack32ToFlat(&status));
    1173 
    1174                 if ( ((status.state != SNDRV_PCM_STATE_PREPARED) &&
    1175                       (status.state != SNDRV_PCM_STATE_RUNNING) &&
    1176                       (status.state != SNDRV_PCM_STATE_DRAINING)) || ret == -32 ) {
    1177                     ret1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0);
    1178                     printk("OSS32_WaveAddBuffer buffer overrun: size %i, ret %i, trans %i, prev sz %i per sz %i total %i\n", size, ret, transferred, prev_size, per_bytes, total);
    1179                     //ret = size;
    1180                     //transferred = size;
    1181                     if (toret) break; /* avoid infinite loop */
    1182                     toret = 1;
    1183                     goto again;
    1184                 }
    1185                 else {
    1186                     printk("OSS32_WaveAddBuffer failed when SNDRV_MINOR_PCM_PLAYBACK. rc = %i\n",ret);
    1187                     printk("hw %i app %i avail %i, size %i\n", samples_to_bytes(status.hw_ptr), samples_to_bytes(status.appl_ptr), samples_to_bytes(status.avail), size);
    1188                     printk("total = %i\n",total);
    1189                     printk("state = %i\n",status.state);
    1190                     printk("avail = %i\n",status.avail);
    1191                     printk("size req = %i\n",size1);
    1192                     DebugInt3();
    1193                     return UNIXToOSSError(transferred);
    1194                 }
    1195             }
    1196             if(ret == 0) {
    1197                 break;
    1198             }
    1199             toret = 0;
    1200             transferred += ret;
    1201 //            printk("written: now: %i, buffer: %i, total: %i\n", ret, transferred, total);
    1202             buffer += ret;
    1203             size   -= ret;
    1204             if((int)size <= 0) {
    1205                 break;
    1206             }
     1138        // size should be aligned to channels number * samplesize  //PS+++ what is it and why?!?!?!
     1139        j = 10;            // 10 try if error
     1140        while (size && j && ret)
     1141        {
     1142               for (i=0; i < 1000; i++)
     1143               {
     1144                     ret1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)__Stack32ToFlat(&status));
     1145                     // If here any state and have free buffer to any byte
     1146                     if ((status.state != SNDRV_PCM_STATE_XRUN ) && samples_to_bytes(status.avail) )
     1147                         break;
     1148                     if (i > 998)
     1149                     {
     1150//                         printk("timeout stat %x avail:%d hw:%d app:%d\n",status.state,samples_to_bytes(status.avail),samples_to_bytes(status.hw_ptr), samples_to_bytes(status.appl_ptr));
     1151                         ret1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0);
     1152                     }
     1153               }
     1154
     1155               if (ret1 < 0)
     1156               {
     1157//                   printk("Status Error ret1:%i trans: %i need %d tot:%d\n",ret1,transferred, size,size1);
     1158                   break;     // We have any global error, don't try more
     1159               }
     1160
     1161               ret = pHandle->file.f_op->write(&pHandle->file, (char *)buffer, size, &pHandle->file.f_pos);
     1162
     1163               if (ret < 0 )
     1164               {  // We have any error, don't try more
     1165                  j--;
     1166                  if ( ret != -11 )
     1167                      ret1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0);
     1168//                  printk("Error ret:%i ret1:%i trans: %d need %d tot:%d\n",ret,ret1,transferred, size,size1);
     1169                  continue;
     1170               }
     1171               if (ret == 0)  continue;
     1172               transferred += ret;
     1173//               printk("written: now: %d, trans: %d need %d tot:%d\n", ret, transferred, size,size1);
     1174               buffer += ret;
     1175               if (size > ret)
     1176                  size   -= ret;
     1177               else
     1178                  size = 0;
    12071179        }
    12081180        break;
     
    12151187        return OSSERR_INVALID_PARAMETER;
    12161188    }
    1217     if(ret < 0) {
    1218         dprintf(("OSS32_WaveAddBuffer failed"));
    1219         DebugInt3();
    1220         return UNIXToOSSError(transferred);
    1221     }
    1222 
    1223     total+=transferred;
     1189
     1190    total += transferred;
    12241191    *pTransferred = transferred;
    12251192    prev_size = transferred;
    1226     if (transferred < size)
    1227     {
    1228         printk("warning: transferred [%i] less than requested [%i]\n", transferred, size);
    1229         ret1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0);
     1193    if (*pTransferred < size1)
     1194    {
     1195        printk("warning: transferred [%d] less than requested [%d]\n", *pTransferred, size1);
     1196//        ret1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0);
    12301197    }
    12311198
     
    12921259        return UNIXToOSSError(ret);
    12931260    }
    1294     *pBytesAvail = samples_to_bytes(status.avail);
     1261    ret = samples_to_bytes(status.avail);
     1262    *pBytesAvail = ret > 752? ret - 752 : 0;
    12951263    return OSSERR_SUCCESS;
    12961264}
Note: See TracChangeset for help on using the changeset viewer.