LMS 2012
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
c_sound.c
Go to the documentation of this file.
1 /*
2  * LEGO® MINDSTORMS EV3
3  *
4  * Copyright (C) 2010-2013 The LEGO Group
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  */
20 
37 #include "c_sound.h"
38 #include "lms2012.h"
39 
40 #if (HARDWARE != SIMULATION)
41 
42  #include <stdio.h>
43  #include <fcntl.h>
44  #include <stdlib.h>
45  #include <unistd.h>
46  #include <sys/mman.h>
47  // #include <sys/stat.h>
48 
50 
51 #else
52 
54 
55  void setSoundInstance(SOUND_GLOBALS * _Instance)
56  {
57  gSoundInstance= _Instance;
58  }
59 
61  {
62  return gSoundInstance;
63  }
64 
65 #endif
66 
67 #ifdef DEBUG_C_SOUND
68  #define DEBUG
69 #endif
70 
71 RESULT cSoundInit(void)
72 {
73  RESULT Result = FAIL;
74  SOUND *pSoundTmp;
75  int SndFile;
76 
77  SoundInstance.SoundDriverDescriptor = -1;
78  SoundInstance.hSoundFile = -1;
79  SoundInstance.pSound = &SoundInstance.Sound;
80 
81  // Create a Shared Memory entry for signaling the driver state BUSY or NOT BUSY
82 
83  SndFile = open(SOUND_DEVICE_NAME,O_RDWR | O_SYNC);
84 
85  if(SndFile >= 0)
86  {
87  pSoundTmp = (SOUND*)mmap(0, sizeof(UWORD), PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, SndFile, 0);
88 
89  if(pSoundTmp == MAP_FAILED)
90  {
92  }
93  else
94  {
95  SoundInstance.pSound = pSoundTmp;
96  Result = OK;
97  }
98 
99  close(SndFile);
100  }
101 
102  return (Result);
103 }
104 
105 RESULT cSoundOpen(void)
106 {
107  RESULT Result = FAIL;
108 
109  Result = OK;
110 
111  return (Result);
112 }
113 
114 RESULT cSoundClose(void)
115 {
116  RESULT Result = FAIL;
117  UWORD BytesToWrite;
118  DATA8 SoundData[SOUND_FILE_BUFFER_SIZE + 1]; // Add up for CMD
119 
120  SoundData[0] = BREAK;
121  BytesToWrite = 1;
122  SoundInstance.SoundDriverDescriptor = open(SOUND_DEVICE_NAME, O_WRONLY);
123  if (SoundInstance.SoundDriverDescriptor >= 0)
124  {
125  write(SoundInstance.SoundDriverDescriptor, SoundData, BytesToWrite);
126  close(SoundInstance.SoundDriverDescriptor);
127  SoundInstance.SoundDriverDescriptor = -1;
128  }
129  SoundInstance.cSoundState = SOUND_STOPPED;
130 
131  if (SoundInstance.hSoundFile >= 0)
132  {
133  close(SoundInstance.hSoundFile);
134  SoundInstance.hSoundFile = -1;
135  }
136 
137  Result = OK;
138 
139  return (Result);
140 }
141 
142 void cSoundInitAdPcm(void)
143 {
144  // Reset ADPCM values to a known and initial value
145  SoundInstance.ValPrev = SOUND_ADPCM_INIT_VALPREV;
146  SoundInstance.Index = SOUND_ADPCM_INIT_INDEX;
147  SoundInstance.Step = StepSizeTable[SoundInstance.Index];
148 
149 }
150 
151 UBYTE cSoundGetAdPcmValue(UBYTE Delta) // Call ONLY when cSoundInitAdPcm has been called :-)
152 {
153  SWORD VpDiff;
154  UBYTE Sign;
155 
156  //
157  SoundInstance.Step = StepSizeTable[SoundInstance.Index];
158  SoundInstance.Index += IndexTable[Delta]; // Find new index value (for later)
159 
160  if(SoundInstance.Index < 0)
161  SoundInstance.Index = 0;
162  else
163  {
164  if(SoundInstance.Index > (STEP_SIZE_TABLE_ENTRIES - 1))
165  SoundInstance.Index = STEP_SIZE_TABLE_ENTRIES - 1;
166  }
167 
168  Sign = Delta & 8; // Separate sign
169  Delta = Delta & 7; // Separate magnitude
170 
171  VpDiff = SoundInstance.Step >> 3; // Compute difference and new predicted value
172 
173  if(Delta & 4) VpDiff += SoundInstance.Step;
174  if(Delta & 2) VpDiff += SoundInstance.Step >> 1;
175  if(Delta & 1) VpDiff += SoundInstance.Step >> 2;
176 
177  if(Sign)
178  SoundInstance.ValPrev -= VpDiff; // "Add" with sign
179  else
180  SoundInstance.ValPrev += VpDiff;
181 
182  if(SoundInstance.ValPrev > 255) // Clamp value to 8-bit unsigned
183  {
184  SoundInstance.ValPrev = 255;
185  }
186  else
187  {
188  if(SoundInstance.ValPrev < 0)
189  {
190  SoundInstance.ValPrev = 0;
191  }
192  }
193 
194  SoundInstance.Step = StepSizeTable[SoundInstance.Index]; // Update step value
195 
196  return((UBYTE)SoundInstance.ValPrev); // Return decoded byte (nibble xlated -> 8 bit)
197 }
198 
199 RESULT cSoundUpdate(void)
200 {
201  int BytesRead;
202  int i;
203  UBYTE AdPcmData[SOUND_ADPCM_CHUNK]; // Temporary ADPCM input buffer
204  UWORD BytesToRead;
205  UBYTE BytesWritten = 0;
206  RESULT Result = FAIL;
207 
208  switch(SoundInstance.cSoundState)
209  {
210  case SOUND_STOPPED: // Do nothing
211  break;
212 
213  case SOUND_SETUP_FILE: // Keep hands off - should only appear, when needed... but...
214  break;
215 
216  case SOUND_FILE_LOOPING: // Make it looping!!
217  // Fall through
218 
219  case SOUND_FILE_PLAYING: if(SoundInstance.BytesToWrite > 0) // Do we have "NOT WRITTEN DATA"
220  {
221  // Yes, write the pending stuff to Driver
222  SoundInstance.SoundDriverDescriptor = open(SOUND_DEVICE_NAME, O_WRONLY);
223  if (SoundInstance.SoundDriverDescriptor >= 0)
224  {
225  BytesWritten = write(SoundInstance.SoundDriverDescriptor, SoundInstance.SoundData, SoundInstance.BytesToWrite);
226  close(SoundInstance.SoundDriverDescriptor);
227  SoundInstance.SoundDriverDescriptor = -1;
228  Result = OK;
229  // Adjust BytesToWrite with Bytes actually written
230  if (BytesWritten > 1)
231  {
232  if(SoundInstance.SoundFileFormat == FILEFORMAT_ADPCM_SOUND)
233  {
234  SoundInstance.SoundDataLength -= (UBYTE)(BytesWritten / 2); // nibbles in file
235  SoundInstance.BytesToWrite -= (UBYTE)(BytesWritten + 1); // Buffer data incl. CMD
236  }
237  else
238  {
239  SoundInstance.SoundDataLength -= BytesWritten;
240  SoundInstance.BytesToWrite -= (UBYTE)(BytesWritten + 1); // Buffer data incl. CMD
241  }
242  }
243  }
244  else
245  {
246  // ERROR!!!!! in writing to driver
247  SoundInstance.cSoundState = SOUND_STOPPED; // Couldn't do the job :-(
248  if (SoundInstance.hSoundFile >= 0)
249  {
250  close(SoundInstance.hSoundFile);
251  SoundInstance.hSoundFile = -1;
252  }
253 
254  }
255  }
256  else // Get new sound data
257  { // No pending stuff
258  if(SoundInstance.SoundDataLength > 0) // Any new data?
259  {
260  SoundInstance.SoundData[0] = SERVICE;
261 
262  if(SoundInstance.SoundFileFormat == FILEFORMAT_ADPCM_SOUND)
263  {
264  // Adjust the chunk size for ADPCM (nibbles) if necessary
265  if (SoundInstance.SoundDataLength > SOUND_ADPCM_CHUNK)
266  BytesToRead = SOUND_ADPCM_CHUNK;
267  else
268  BytesToRead = SoundInstance.SoundDataLength;
269 
270  if(SoundInstance.hSoundFile >= 0) // Valid file
271  {
272  BytesRead = read(SoundInstance.hSoundFile,AdPcmData,BytesToRead);
273 
274  for(i = 0; i < BytesRead; i++)
275  {
276  SoundInstance.SoundData[2*i + 1] = cSoundGetAdPcmValue((AdPcmData[i] >> 4) & 0x0F);
277  SoundInstance.SoundData[2*i + 2] = cSoundGetAdPcmValue(AdPcmData[i] & 0x0F);
278  }
279 
280  SoundInstance.BytesToWrite = (UBYTE) (1 + BytesRead * 2);
281  }
282  }
283  else // Non compressed data
284  {
285  // Adjust the chunk size if necessary
286  if (SoundInstance.SoundDataLength > SOUND_CHUNK)
287  BytesToRead = SOUND_CHUNK;
288  else
289  BytesToRead = SoundInstance.SoundDataLength;
290 
291  if(SoundInstance.hSoundFile >= 0) // Valid file
292  {
293  BytesRead = read(SoundInstance.hSoundFile,&(SoundInstance.SoundData[1]),BytesToRead);
294 
295  SoundInstance.BytesToWrite = BytesRead + 1;
296  }
297  }
298  // Now we have or should have some bytes to write down into the driver
299  SoundInstance.SoundDriverDescriptor = open(SOUND_DEVICE_NAME, O_WRONLY);
300  if (SoundInstance.SoundDriverDescriptor >= 0)
301  {
302  BytesWritten = write(SoundInstance.SoundDriverDescriptor, SoundInstance.SoundData, SoundInstance.BytesToWrite);
303  close(SoundInstance.SoundDriverDescriptor);
304  SoundInstance.SoundDriverDescriptor = -1;
305  Result = OK;
306 
307  // Adjust BytesToWrite with Bytes actually written
308  if (BytesWritten > 1)
309  {
310  if(SoundInstance.SoundFileFormat == FILEFORMAT_ADPCM_SOUND)
311  {
312  SoundInstance.SoundDataLength -= (UBYTE)(BytesWritten / 2); // nibbles in file
313  SoundInstance.BytesToWrite -= (UBYTE)(BytesWritten + 1); // Buffer data incl. CMD
314  }
315  else
316  {
317  SoundInstance.SoundDataLength -= BytesWritten;
318  SoundInstance.BytesToWrite -= (UBYTE)(BytesWritten + 1); // Buffer data incl. CMD
319  }
320  }
321  }
322  else
323  {
324  // ERROR!!!!! in writing to driver
325  SoundInstance.cSoundState = SOUND_STOPPED; // Couldn't do the job :-(
326  if (SoundInstance.hSoundFile >= 0)
327  {
328  close(SoundInstance.hSoundFile);
329  SoundInstance.hSoundFile = -1;
330  }
331 
332  }
333 
334  } // end new data
335  else // Shut down the SOUND stuff until new request/data i.e.
336  { // SoundDataLength > 0
337 
338  if(SoundInstance.cSoundState == SOUND_FILE_LOOPING)
339  {
340  lseek(SoundInstance.hSoundFile, 0, SEEK_SET);
341  stat(SoundInstance.PathBuffer,&SoundInstance.FileStatus);
342  SoundInstance.SoundDataLength = SoundInstance.FileStatus.st_size;
343  // TODO make a new write here, so no zero-"sound"
344 
345  }
346  else
347  {
348  SoundInstance.cSoundState = SOUND_STOPPED;
349 
350  if (SoundInstance.hSoundFile >= 0)
351  {
352  close(SoundInstance.hSoundFile);
353  SoundInstance.hSoundFile = -1;
354  }
355 
356  if (SoundInstance.SoundDriverDescriptor >= 0)
357  {
358  close(SoundInstance.SoundDriverDescriptor);
359  SoundInstance.SoundDriverDescriptor = -1;
360  }
361 
362  }
363 
364  }
365  } // No pending write
366  break;
367 
368  case SOUND_TONE_PLAYING: // Check for duration done in d_sound :-)
369 
370  if ((*SoundInstance.pSound).Status == OK)
371  {
372  // DO the finished stuff
373  SoundInstance.cSoundState = SOUND_STOPPED;
374  if (SoundInstance.SoundDriverDescriptor >= 0)
375  {
376  close(SoundInstance.SoundDriverDescriptor);
377  SoundInstance.SoundDriverDescriptor = -1;
378  }
379 
380  if (SoundInstance.hSoundFile >= 0)
381  {
382  close(SoundInstance.hSoundFile);
383  SoundInstance.hSoundFile = -1;
384  }
385 
386  Result = OK;
387  }
388  break;
389 
390  default: // Do nothing
391  break;
392  }
393  return (Result);
394 }
395 
396 RESULT cSoundExit(void)
397 {
398  RESULT Result = FAIL;
399 
400  Result = OK;
401 
402  return (Result);
403 }
404 
405 //******* BYTE CODE SNIPPETS **************************************************
406 
440 void cSoundEntry(void)
441 {
442  int Cmd;
443  UWORD Temp1;
444  UBYTE Loop = FALSE;
445  UWORD Frequency;
446  UWORD Duration;
447 
448  UWORD BytesToWrite;
449  UWORD BytesWritten = 0;
450  DATA8 SoundData[SOUND_FILE_BUFFER_SIZE + 1]; // Add up for CMD
451 
452  DATA8 *pFileName;
453  char PathName[MAX_FILENAME_SIZE];
454  UBYTE Tmp1;
455  UBYTE Tmp2;
456 
457 
458  Cmd = *(DATA8*)PrimParPointer();
459 
460  SoundData[0] = Cmd; // General for all commands :-)
461  BytesToWrite = 0;
462 
463 
464  switch(Cmd)
465  {
466 
467  case TONE: (*SoundInstance.pSound).Status = BUSY;
468  SoundInstance.SoundOwner = CallingObjectId();
469  Temp1 = *(DATA8*)PrimParPointer(); // Volume level
470 
471  // Scale the volume from 1-100% into 13 level steps
472  // Could be linear but prepared for speaker and -box adjustments... :-)
473  if(Temp1 > 0)
474  {
475  if(Temp1 > TONE_LEVEL_6) // > 48%
476  {
477  if(Temp1 > TONE_LEVEL_9) // > 72%
478  {
479  if(Temp1 > TONE_LEVEL_11) // > 88%
480  {
481  if(Temp1 > TONE_LEVEL_12) // > 96%
482  {
483  SoundData[1] = 13; // => 100%
484  }
485  else
486  {
487  SoundData[1] = 12; // => 100%
488  }
489  }
490  else
491  {
492  if(Temp1 > TONE_LEVEL_10) // > 96%
493  {
494  SoundData[1] = 11; // => 100%
495  }
496  else
497  {
498  SoundData[1] = 10; // => 100%
499  }
500  }
501  }
502  else
503  {
504  if(Temp1 > TONE_LEVEL_8) // > 62.5%
505  {
506  SoundData[1] = 9; // => 75%
507  }
508  else
509  {
510  if(Temp1 > TONE_LEVEL_7)
511  {
512  SoundData[1] = 8; // => 62.5%
513  }
514  else
515  {
516  SoundData[1] = 7; // => 62.5%
517  }
518  }
519  }
520  }
521  else
522  {
523  if(Temp1 > TONE_LEVEL_3) // > 25%
524  {
525  if(Temp1 > TONE_LEVEL_5) // > 37.5%
526  {
527  SoundData[1] = 6; // => 50%
528  }
529  else
530  {
531  if(Temp1 > TONE_LEVEL_4) // > 37.5%
532  {
533  SoundData[1] = 5; // => 37.5%
534  }
535  else
536  {
537  SoundData[1] = 4;
538  }
539  }
540  }
541  else
542  {
543  if(Temp1 > TONE_LEVEL_2) // > 12.5%
544  {
545  SoundData[1] = 3;
546  }
547  else
548  {
549  if(Temp1 > TONE_LEVEL_1)
550  {
551  SoundData[1] = 2; // => 25%
552  }
553  else
554  {
555  SoundData[1] = 1; // => 25%
556  }
557  }
558  } }
559  }
560  else
561  SoundData[1] = 0;
562 
563  Frequency = *(DATA16*)PrimParPointer();
564  Duration = *(DATA16*)PrimParPointer();
565  SoundData[2] = (UBYTE)(Frequency);
566  SoundData[3] = (UBYTE)(Frequency >> 8);
567  SoundData[4] = (UBYTE)(Duration);
568  SoundData[5] = (UBYTE)(Duration >> 8);
569  BytesToWrite = 6;
570  SoundInstance.cSoundState = SOUND_TONE_PLAYING;
571  break;
572 
573  case BREAK: //SoundData[0] = Cmd;
574  BytesToWrite = 1;
575  SoundInstance.cSoundState = SOUND_STOPPED;
576 
577  if (SoundInstance.hSoundFile >= 0)
578  {
579  close(SoundInstance.hSoundFile);
580  SoundInstance.hSoundFile = -1;
581  }
582 
583  break;
584 
585  case REPEAT: Loop = TRUE;
586  SoundData[0] = PLAY; // Yes, but looping :-)
587  // Fall through
588 
589  case PLAY: // If SoundFile is Flood filled, we must politely
590  // close the active handle - else we acts as a "BUG"
591  // eating all the crops (handles) ;-)
592 
593  SoundInstance.cSoundState = SOUND_STOPPED; // Yes but only shortly
594 
595  if (SoundInstance.hSoundFile >= 0) // An active handle?
596  {
597  close(SoundInstance.hSoundFile); // No more use
598  SoundInstance.hSoundFile = -1; // Signal it
599  }
600 
601  (*SoundInstance.pSound).Status = BUSY;
602  SoundInstance.SoundOwner = CallingObjectId();
603 
604  Temp1 = *(DATA8*)PrimParPointer(); // Volume level
605  // Scale the volume from 1-100% into 1 - 8 level steps
606  // Could be linear but prepared for speaker and -box adjustments... :-)
607  if(Temp1 > 0)
608  {
609  if(Temp1 > SND_LEVEL_4) // > 50%
610  {
611  if(Temp1 > SND_LEVEL_6) // > 75%
612  {
613  if(Temp1 > SND_LEVEL_7) // > 87.5%
614  {
615  SoundData[1] = 8; // => 100%
616  }
617  else
618  {
619  SoundData[1] = 7; // => 87.5%
620  }
621  }
622  else
623  {
624  if(Temp1 > SND_LEVEL_5) // > 62.5%
625  {
626  SoundData[1] = 6; // => 75%
627  }
628  else
629  {
630  SoundData[1] = 5; // => 62.5%
631  }
632  }
633  }
634  else
635  {
636  if(Temp1 > SND_LEVEL_2) // > 25%
637  {
638  if(Temp1 > SND_LEVEL_3) // > 37.5%
639  {
640  SoundData[1] = 4; // => 50%
641  }
642  else
643  {
644  SoundData[1] = 3; // => 37.5%
645  }
646  }
647  else
648  {
649  if(Temp1 > SND_LEVEL_1) // > 12.5%
650  {
651  SoundData[1] = 2; // => 25%
652  }
653  else
654  {
655  SoundData[1] = 1; // => 12.5%
656  }
657  }
658  }
659  }
660  else
661  SoundData[1] = 0;
662 
663  BytesToWrite = 2;
664 
665  // Get filename
666  pFileName = (DATA8*)PrimParPointer();
667 
668  if(pFileName != NULL) // We should have a valid filename
669  {
670  // Get Path and concatenate
671 
672  PathName[0] = 0;
673  if (pFileName[0] != '.')
674  {
675  GetResourcePath(PathName, MAX_FILENAME_SIZE);
676  sprintf(SoundInstance.PathBuffer, "%s%s.rsf", (char*)PathName, (char*)pFileName);
677  }
678  else
679  {
680  sprintf(SoundInstance.PathBuffer, "%s.rsf", (char*)pFileName);
681  }
682 
683  // Open SoundFile
684 
685  SoundInstance.hSoundFile = open(SoundInstance.PathBuffer,O_RDONLY,0666);
686 
687  if(SoundInstance.hSoundFile >= 0)
688  {
689  // Get actual FileSize
690  stat(SoundInstance.PathBuffer,&SoundInstance.FileStatus);
691  SoundInstance.SoundFileLength = SoundInstance.FileStatus.st_size;
692 
693  // BIG Endianess
694 
695  read(SoundInstance.hSoundFile,&Tmp1,1);
696  read(SoundInstance.hSoundFile,&Tmp2,1);
697  SoundInstance.SoundFileFormat = (UWORD)Tmp1 << 8 | (UWORD)Tmp2;
698 
699  read(SoundInstance.hSoundFile,&Tmp1,1);
700  read(SoundInstance.hSoundFile,&Tmp2,1);
701  SoundInstance.SoundDataLength = (UWORD)Tmp1 << 8 | (UWORD)Tmp2;
702 
703  read(SoundInstance.hSoundFile,&Tmp1,1);
704  read(SoundInstance.hSoundFile,&Tmp2,1);
705  SoundInstance.SoundSampleRate = (UWORD)Tmp1 << 8 | (UWORD)Tmp2;
706 
707  read(SoundInstance.hSoundFile,&Tmp1,1);
708  read(SoundInstance.hSoundFile,&Tmp2,1);
709  SoundInstance.SoundPlayMode = (UWORD)Tmp1 << 8 | (UWORD)Tmp2;
710 
711  SoundInstance.cSoundState = SOUND_SETUP_FILE;
712 
713  if(SoundInstance.SoundFileFormat == FILEFORMAT_ADPCM_SOUND)
714  cSoundInitAdPcm();
715  }
716 
717 
718  }
719  else
720  {
721  //Do some ERROR-handling :-)
722  //NOT a valid name from above :-(
723  }
724 
725  break;
726 
727  default: BytesToWrite = 0; // An non-valid entry
728  break;
729  }
730 
731  if(BytesToWrite > 0)
732  {
733  SoundInstance.SoundDriverDescriptor = open(SOUND_DEVICE_NAME, O_WRONLY);
734  if (SoundInstance.SoundDriverDescriptor >= 0)
735  {
736  BytesWritten = write(SoundInstance.SoundDriverDescriptor, SoundData, BytesToWrite);
737  close(SoundInstance.SoundDriverDescriptor);
738  SoundInstance.SoundDriverDescriptor = -1;
739 
740  if (SoundInstance.cSoundState == SOUND_SETUP_FILE) // The one and only situation
741  {
742  SoundInstance.BytesToWrite = 0; // Reset
743  if(TRUE == Loop)
744  SoundInstance.cSoundState = SOUND_FILE_LOOPING;
745  else
746  SoundInstance.cSoundState = SOUND_FILE_PLAYING;
747  }
748  }
749  else
750  SoundInstance.cSoundState = SOUND_STOPPED; // Couldn't do the job :-(
751  }
752  else
753  {
754  BytesToWrite = BytesWritten;
755  BytesToWrite = 0;
756  }
757 }
758 
773 void cSoundTest(void)
774 {
775  if ((*SoundInstance.pSound).Status == BUSY)
776  {
777  *(DATA8*)PrimParPointer() = 1;
778  }
779  else
780  {
781  *(DATA8*)PrimParPointer() = 0;
782  }
783 }
784 
797 void cSoundReady(void)
798 {
799  IP TmpIp;
800  DSPSTAT DspStat = NOBREAK;
801 
802  TmpIp = GetObjectIp();
803 
804  if ((*SoundInstance.pSound).Status == BUSY)
805  { // If BUSY check for OVERRULED
806 
807  { // Rewind IP and set status
808  DspStat = BUSYBREAK; // break the interpreter and waits busy
809  SetDispatchStatus(DspStat);
810  SetObjectIp(TmpIp - 1);
811  }
812  }
813 }
int hSoundFile
Definition: c_sound.h:115
void SetDispatchStatus(DSPSTAT DspStat)
Set object (dispatch) status.
Definition: lms2012.c:256
#define TONE_LEVEL_8
Definition: c_sound.h:59
Definition: lms2012.h:558
#define TONE_LEVEL_9
Definition: c_sound.h:60
#define SND_LEVEL_4
Definition: c_sound.h:47
const SWORD StepSizeTable[STEP_SIZE_TABLE_ENTRIES]
Definition: c_sound.h:68
void cSoundInitAdPcm(void)
Definition: c_sound.c:142
void cSoundEntry(void)
opSOUND byte code
Definition: c_sound.c:440
SWORD DATA16
VM Type for 2 byte signed value.
Definition: lmstypes.h:62
void LogErrorNumber(ERR Err)
Definition: lms2012.c:445
#define TONE_LEVEL_4
Definition: c_sound.h:55
#define SND_LEVEL_3
Definition: c_sound.h:46
void SetObjectIp(IP Ip)
Set current instruction pointer.
Definition: lms2012.c:309
UBYTE BytesToWrite
Definition: c_sound.h:130
UWORD SoundPlayMode
Definition: c_sound.h:125
void setSoundInstance(SOUND_GLOBALS *_Instance)
Definition: c_sound.c:55
void * PrimParPointer(void)
Get next encoded parameter from byte code stream.
Definition: lms2012.c:694
Definition: lms2012.h:557
#define SOUND_CHUNK
Definition: lms2012.h:529
#define TONE_LEVEL_1
Definition: c_sound.h:52
IP GetObjectIp(void)
Get current instruction pointer.
Definition: lms2012.c:298
SWORD Step
Definition: c_sound.h:129
struct stat FileStatus
Definition: c_sound.h:132
OBJID CallingObjectId(void)
Get calling object id.
Definition: lms2012.c:196
RESULT cSoundOpen(void)
Definition: c_sound.c:105
SOUND_GLOBALS * gSoundInstance
Definition: c_sound.c:53
#define TONE_LEVEL_5
Definition: c_sound.h:56
IMGDATA * IP
Instruction pointer type.
Definition: lmstypes.h:74
void GetResourcePath(char *pString, DATA8 MaxLength)
Definition: lms2012.c:360
#define TONE_LEVEL_6
Definition: c_sound.h:57
#define TONE_LEVEL_2
Definition: c_sound.h:53
#define TONE_LEVEL_10
Definition: c_sound.h:61
#define SOUND_FILE_BUFFER_SIZE
Definition: lms2012.h:536
#define SND_LEVEL_7
Definition: c_sound.h:50
UWORD SoundFileFormat
Definition: c_sound.h:122
#define TONE_LEVEL_3
Definition: c_sound.h:54
UWORD SoundSampleRate
Definition: c_sound.h:124
#define SND_LEVEL_5
Definition: c_sound.h:48
DATA8 cSoundState
Definition: c_sound.h:118
RESULT cSoundClose(void)
Definition: c_sound.c:114
void cSoundTest(void)
opSOUND_TEST byte code
Definition: c_sound.c:773
#define TONE_LEVEL_12
Definition: c_sound.h:63
#define SoundInstance
Definition: c_sound.h:139
#define SOUND_ADPCM_INIT_VALPREV
Definition: c_sound.h:105
SWORD Index
Definition: c_sound.h:128
void cSoundReady(void)
opSOUND_READY byte code
Definition: c_sound.c:797
SOUND Sound
Definition: c_sound.h:119
SOUND * pSound
Definition: c_sound.h:120
#define SND_LEVEL_6
Definition: c_sound.h:49
int BytesWritten
Definition: c_daisy.c:67
RESULT cSoundExit(void)
Definition: c_sound.c:396
UWORD SoundFileLength
Definition: c_sound.h:126
unsigned char UBYTE
Basic Type used to symbolise 8 bit unsigned values.
Definition: lmstypes.h:29
SOUND_GLOBALS * getSoundInstance()
Definition: c_sound.c:60
char PathBuffer[MAX_FILENAME_SIZE]
Definition: c_sound.h:131
UWORD SoundDataLength
Definition: c_sound.h:123
RESULT cSoundInit(void)
Definition: c_sound.c:71
#define SOUND_ADPCM_CHUNK
Definition: lms2012.h:530
unsigned short UWORD
Basic Type used to symbolise 16 bit unsigned values.
Definition: lmstypes.h:30
UBYTE cSoundGetAdPcmValue(UBYTE Delta)
Definition: c_sound.c:151
signed short SWORD
Basic Type used to symbolise 16 bit signed values.
Definition: lmstypes.h:34
#define FILEFORMAT_ADPCM_SOUND
Definition: c_sound.h:102
const SWORD IndexTable[INDEX_TABLE_ENTRIES]
Definition: c_sound.h:79
#define SND_LEVEL_1
Definition: c_sound.h:44
#define STEP_SIZE_TABLE_ENTRIES
Definition: c_sound.h:29
#define SOUND_ADPCM_INIT_INDEX
Definition: c_sound.h:106
SBYTE DATA8
VM Type for 1 byte signed value.
Definition: lmstypes.h:61
UBYTE SoundData[SOUND_FILE_BUFFER_SIZE+1]
Definition: c_sound.h:133
RESULT cSoundUpdate(void)
Definition: c_sound.c:199
SWORD ValPrev
Definition: c_sound.h:127
DSPSTAT
Definition: lms2012.h:665
int SoundDriverDescriptor
Definition: c_sound.h:114
#define TONE_LEVEL_11
Definition: c_sound.h:62
Break because of waiting for completion.
Definition: lms2012.h:671
Dispatcher running (looping)
Definition: lms2012.h:667
DATA8 SoundOwner
Definition: c_sound.h:117
#define TONE_LEVEL_7
Definition: c_sound.h:58
#define SND_LEVEL_2
Definition: c_sound.h:45
#define NULL