| version 1.2 | | version 1.3 |
|---|
| | |
| #include <stdlib.h> | | #include <stdlib.h> |
| #include <stdio.h> | | #include <stdio.h> |
| #include <string.h> | | #include <string.h> |
| #include <sys/asoundlib.h> | | #include <alsa/asoundlib.h> |
| #include <pthread.h> | | #include <pthread.h> |
| | | |
| #include "error.h" | | #include "error.h" |
| | |
| /* Threading/ALSA stuff */ | | /* Threading/ALSA stuff */ |
| #define LOCK() pthread_mutex_lock(&mutex) | | #define LOCK() pthread_mutex_lock(&mutex) |
| #define UNLOCK() pthread_mutex_unlock(&mutex) | | #define UNLOCK() pthread_mutex_unlock(&mutex) |
| void *snd_devhandle; | | snd_pcm_t *snd_devhandle; |
| pthread_t thread_id; | | pthread_t thread_id; |
| pthread_mutex_t mutex; | | pthread_mutex_t mutex; |
| | | |
| | |
| sldata = sl->samples; | | sldata = sl->samples; |
| } | | } |
| v = *(sldata++) - 0x80; | | v = *(sldata++) - 0x80; |
| *(sp++) = mix8[ *sp + fixmul(v, vl) + 0x80 ]; | | |
| *(sp++) = mix8[ *sp + fixmul(v, vr) + 0x80 ]; | | *sp = mix8[ *sp + fixmul(v, vl) + 0x80 ]; |
| | | sp++; |
| | | |
| | | *sp = mix8[ *sp + fixmul(v, vr) + 0x80 ]; |
| | | sp++; |
| } | | } |
| sl->position = sldata - sl->samples; | | sl->position = sldata - sl->samples; |
| } | | } |
| | |
| //end changes by adb | | //end changes by adb |
| | | |
| void *mixer_thread(void *data) { | | void *mixer_thread(void *data) { |
| // int i=0; | | int err; |
| ubyte buffer[512]; | | ubyte buffer[SOUND_BUFFER_SIZE]; |
| | | |
| /* Allow ourselves to be asynchronously cancelled */ | | /* Allow ourselves to be asynchronously cancelled */ |
| pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); | | pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); |
| while (1) { | | while (1) { |
| // printf("i=%d\n",i++); | | |
| memset(buffer, 0x80, 512); | | memset(buffer, 0x80, SOUND_BUFFER_SIZE); |
| LOCK(); | | LOCK(); |
| audio_mixcallback(NULL,buffer,512); | | audio_mixcallback(NULL,buffer,SOUND_BUFFER_SIZE); |
| UNLOCK(); | | UNLOCK(); |
| snd_pcm_write(snd_devhandle, buffer, 512); | | again: |
| | | err = snd_pcm_writei(snd_devhandle, buffer, SOUND_BUFFER_SIZE/2); |
| | | |
| | | if (err == -EPIPE) { |
| | | // Sound buffer underrun |
| | | err = snd_pcm_prepare(snd_devhandle); |
| | | if (err < 0) { |
| | | fprintf(stderr, "Can't recover from underrun: %s\n", |
| | | snd_strerror(err)); |
| | | } |
| | | } else if (err == -EAGAIN) { |
| | | goto again; |
| | | } else if (err != SOUND_BUFFER_SIZE/2) { |
| | | // Each frame has size 2 bytes - hence we expect SOUND_BUFFER_SIZE/2 |
| | | // frames to be written. |
| | | fprintf(stderr, "Unknown err %d: %s\n", err, snd_strerror(err)); |
| | | } |
| } | | } |
| return 0; | | return 0; |
| } | | } |
| | |
| /* Initialise audio devices. */ | | /* Initialise audio devices. */ |
| int digi_init() | | int digi_init() |
| { | | { |
| int card=0, device=0, err; | | int err, tmp; |
| snd_pcm_format_t format; | | char *device = "plughw:0,0"; |
| snd_pcm_playback_params_t params; | | snd_pcm_hw_params_t *params; |
| pthread_attr_t attr; | | pthread_attr_t attr; |
| pthread_mutexattr_t mutexattr; | | pthread_mutexattr_t mutexattr; |
| | | |
| | |
| //end edit by adb | | //end edit by adb |
| | | |
| /* Open the ALSA sound device */ | | /* Open the ALSA sound device */ |
| if ((err = snd_pcm_open(&snd_devhandle, card, device, | | if ((err = snd_pcm_open(&snd_devhandle,device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { |
| SND_PCM_OPEN_PLAYBACK)) < 0) { | | |
| fprintf(stderr, "open failed: %s\n", snd_strerror( err )); | | fprintf(stderr, "open failed: %s\n", snd_strerror( err )); |
| return -1; | | return -1; |
| } | | } |
| | | |
| memset(&format, 0, sizeof(format)); | | snd_pcm_hw_params_alloca(¶ms); |
| format.format = SND_PCM_SFMT_U8; | | err = snd_pcm_hw_params_any(snd_devhandle, params); |
| format.rate = 11025; | | if (err < 0) { |
| format.channels = 2; | | printf("ALSA: Error %s\n", snd_strerror(err)); |
| if ((err = snd_pcm_playback_format(snd_devhandle, &format)) < 0) { | | return -1; |
| fprintf(stderr, "format setup failed: %s\n", snd_strerror( err )); | | } |
| snd_pcm_close( snd_devhandle ); | | err = snd_pcm_hw_params_set_access(snd_devhandle, params, SND_PCM_ACCESS_RW_INTERLEAVED); |
| | | if (err < 0) { |
| | | printf("ALSA: Error %s\n", snd_strerror(err)); |
| | | return -1; |
| | | } |
| | | err = snd_pcm_hw_params_set_format(snd_devhandle, params, SND_PCM_FORMAT_U8); |
| | | if (err < 0) { |
| | | printf("ALSA: Error %s\n", snd_strerror(err)); |
| | | return -1; |
| | | } |
| | | err = snd_pcm_hw_params_set_channels(snd_devhandle, params, 2); |
| | | if (err < 0) { |
| | | printf("ALSA: Error %s\n", snd_strerror(err)); |
| | | return -1; |
| | | } |
| | | tmp = 11025; |
| | | err = snd_pcm_hw_params_set_rate_near(snd_devhandle, params, &tmp, NULL); |
| | | if (err < 0) { |
| | | printf("ALSA: Error %s\n", snd_strerror(err)); |
| return -1; | | return -1; |
| } | | } |
| | | snd_pcm_hw_params_set_periods(snd_devhandle, params, 3, 0); |
| | | snd_pcm_hw_params_set_buffer_size(snd_devhandle,params, (SOUND_BUFFER_SIZE*3)/2); |
| | | |
| memset(¶ms, 0, sizeof(params)); | | err = snd_pcm_hw_params(snd_devhandle, params); |
| params.fragment_size=512; | | if (err < 0) { |
| params.fragments_max=2; | | printf("ALSA: Error %s\n", snd_strerror(err)); |
| params.fragments_room=1; | | |
| if ((err = snd_pcm_playback_params(snd_devhandle, ¶ms)) < 0) { | | |
| fprintf(stderr, "params setup failed: %s\n", snd_strerror( err )); | | |
| snd_pcm_close( snd_devhandle ); | | |
| return -1; | | return -1; |
| } | | } |
| | | |
| | |
| void digi_close() | | void digi_close() |
| { | | { |
| if (!digi_initialised) return; | | if (!digi_initialised) return; |
| | | pthread_cancel(thread_id); |
| digi_initialised = 0; | | digi_initialised = 0; |
| snd_pcm_close(snd_devhandle); | | |
| pthread_mutex_destroy(&mutex); | | pthread_mutex_destroy(&mutex); |
| pthread_cancel(thread_id); | | snd_pcm_close(snd_devhandle); |
| } | | } |
| | | |
| static int get_free_slot() | | static int get_free_slot() |
| | |
| int digi_link_sound_to_pos2( int soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume, fix max_distance ) | | int digi_link_sound_to_pos2( int soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume, fix max_distance ) |
| { | | { |
| int i, volume, pan; | | int i, volume, pan; |
| int soundnum; | | // int soundnum; |
| | | |
| if ( max_volume < 0 ) return -1; | | if ( max_volume < 0 ) return -1; |
| // if ( max_volume > F1_0 ) max_volume = F1_0; | | // if ( max_volume > F1_0 ) max_volume = F1_0; |