/*********************************************************************************************************************** PicoMite MMBasic audio.c Geoff Graham, Peter Mather Copyright (c) 2021, All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name MMBasic be used when referring to the interpreter in any documentation and promotional material and the original copyright message be displayed on the console at startup (additional copyright messages may be added). 4. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by the . 5. Neither the name of the nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ************************************************************************************************************************/ /** * @file Audio.c * @author Geoff Graham, Peter Mather * @brief Source for Audio MMBasic command */ /** * @cond * The following section will be excluded from the documentation. */ #include #include // Pascal #include // Pascal #include "ffconf.h" #include "hardware/pwm.h" #include "hardware/irq.h" #include "hardware/flash.h" #include "MMBasic_Includes.h" #include "Hardware_Includes.h" #define DRWAV_COPY_MEMORY(dst, src, sz) memcpy((dst), (src), (sz)) #define DR_WAV_IMPLEMENTATION #define DR_WAV_NO_SIMD #define DR_WAV_NO_STDIO #include "dr_wav.h" #define DR_FLAC_IMPLEMENTATION #define DR_FLAC_NO_STDIO #define DR_FLAC_NO_CRC #define DR_FLAC_NO_SIMD #define DR_FLAC_NO_OGG #define FLAC_BUFFER_SIZE WAV_BUFFER_SIZE #define DR_MP3_IMPLEMENTATION #define DR_MP3_NO_STDIO //#define DRMP3_COPY_MEMORY(dst, src, sz) memcpy((dst), (src), (sz)) //#define DRMP3_ZERO_MEMORY(p, sz) memset((p), 0, (sz)) //#define DR_MP3_FLOAT_OUTPUT #define DR_MP3_ONLY_MP3 #define DR_MP3_NO_SIMD #define DRMP3_DATA_CHUNK_SIZE 32768 #define MP3_BUFFER_SIZE WAV_BUFFER_SIZE #ifdef rp2350 #include "dr_mp3.h" #define MOD_BUFFER_SIZE WAV_BUFFER_SIZE #else #define MOD_BUFFER_SIZE (WAV_BUFFER_SIZE/4)*3 #endif #include "hardware/pio.h" #include "hardware/pio_instructions.h" #include "dr_flac.h" #include "hxcmod.h" #include "VS1053.h" extern BYTE MDD_SDSPI_CardDetectState(void); #define MAXALBUM 20 extern int InitSDCard(void); extern const int ErrorMap[21]; extern char *GetCWD(void); extern void ErrorCheck(int fnbr); extern const int mapping[101]; extern PIO pioi2s; extern uint8_t i2ssm; /******************************************************************************************************************************************** commands and functions each function is responsible for decoding a command all function names are in the form cmd_xxxx() (for a basic command) or fun_xxxx() (for a basic function) so, if you want to search for the function responsible for the NAME command look for cmd_name There are 4 items of information that are setup before the command is run. All these are globals. int cmdtoken This is the token number of the command (some commands can handle multiple statement types and this helps them differentiate) char *cmdline This is the command line terminated with a zero char and trimmed of leading spaces. It may exist anywhere in memory (or even ROM). char *nextstmt This is a pointer to the next statement to be executed. The only thing a command can do with it is save it or change it to some other location. char *CurrentLinePtr This is read only and is set to NULL if the command is in immediate mode. The only actions a command can do to change the program flow is to change nextstmt or execute longjmp(mark, 1) if it wants to abort the program. ********************************************************************************************************************************************/ // define the PWM output frequency for making a tone const char* const PlayingStr[] = {"PAUSED TONE", "PAUSED FLAC", "PAUSED MP3", "PAUSED SOUND", "PAUSED MOD", "PAUSED WAV", "OFF", "OFF", "TONE", "SOUND", "WAV", "FLAC", "MP3", "MIDI", "", "MOD", "STREAM","" } ; volatile unsigned char PWM_count = 0; volatile float PhaseM_left, PhaseM_right; volatile uint64_t SoundPlay; volatile e_CurrentlyPlaying CurrentlyPlaying = P_NOTHING; volatile int v_left, v_right, vol_left = 100, vol_right = 100; char *wav_buf; // pointer to the buffer for received wav data volatile int wav_filesize; // head and tail of the ring buffer for com1 volatile int tickspersample; char *WAVInterrupt = NULL; bool WAVcomplete; int WAV_fnbr=0; int PWM_FREQ; volatile int swingbuf = 0,nextbuf = 0, playreadcomplete = 1; char *sbuff1=NULL, *sbuff2=NULL; uint16_t *ubuff1, *ubuff2; int16_t *g_buff1, *g_buff2; char *modbuff=NULL; modcontext *mcontext=NULL; int modfilesamplerate=22050; char *pbuffp; void audio_checks(void); uint16_t *playbuff; int16_t *uplaybuff; volatile int ppos = 0; // playing position for PLAY WAV uint8_t nchannels; volatile uint32_t bcount[3] = {0, 0, 0}; volatile int sound_v_left[MAXSOUNDS]={[0 ... MAXSOUNDS-1 ]=25}; volatile int sound_v_right[MAXSOUNDS]={[0 ... MAXSOUNDS-1 ]=25}; volatile float sound_PhaseAC_left[MAXSOUNDS], sound_PhaseAC_right[MAXSOUNDS]; volatile float sound_PhaseM_left[MAXSOUNDS], sound_PhaseM_right[MAXSOUNDS]; volatile unsigned short * sound_mode_left[MAXSOUNDS]; volatile unsigned short * sound_mode_right[MAXSOUNDS]; volatile uint8_t audiorepeat=1; volatile uint8_t mono; //int debug = 0; drwav *mywav; drflac *myflac; a_flist *alist=NULL; uint8_t trackplaying=0, trackstoplay=0; unsigned short *noisetable=NULL; unsigned short *usertable=NULL; const unsigned short whitenoise[2]={0}; int noloop=0; int8_t XDCS=-1,XCS=-1,DREQ=-1,XRST=-1; uint8_t midienabled=0; int streamsize=0; volatile int *streamwritepointer=NULL; volatile int *streamreadpointer=NULL; char *streambuffer=NULL; char WAVfilename[FF_MAX_LFN]={0}; #ifdef rp2350 drmp3 *mymp3; #endif void* my_malloc(size_t sz, void* pUserData) { return GetMemory(sz); } void* my_realloc(void* p, size_t sz, void* pUserData) { return ReAllocMemory((p), (sz)); } void my_free(void* p, void* pUserData) { FreeMemory((void *)p); p=NULL; } //************************************************************************************* volatile float PhaseAC_left, PhaseAC_right; //#define PSpeedDiv (PeripheralBusSpeed)/2 const unsigned short nulltable[1]={97}; const unsigned short squaretable[1]={99}; const unsigned short triangletable[4096]={ 2000,2001,2003,2005,2007,2009,2011,2012,2014,2016,2018,2020,2022,2024,2025,2027, 2029,2031,2033,2035,2037,2038,2040,2042,2044,2046,2048,2050,2051,2053,2055,2057, 2059,2061,2063,2064,2066,2068,2070,2072,2074,2076,2077,2079,2081,2083,2085,2087, 2089,2090,2092,2094,2096,2098,2100,2102,2103,2105,2107,2109,2111,2113,2115,2116, 2118,2120,2122,2124,2126,2128,2129,2131,2133,2135,2137,2139,2141,2142,2144,2146, 2148,2150,2152,2154,2155,2157,2159,2161,2163,2165,2166,2168,2170,2172,2174,2176, 2178,2179,2181,2183,2185,2187,2189,2191,2192,2194,2196,2198,2200,2202,2204,2205, 2207,2209,2211,2213,2215,2217,2218,2220,2222,2224,2226,2228,2230,2231,2233,2235, 2237,2239,2241,2243,2244,2246,2248,2250,2252,2254,2256,2257,2259,2261,2263,2265, 2267,2269,2270,2272,2274,2276,2278,2280,2282,2283,2285,2287,2289,2291,2293,2295, 2296,2298,2300,2302,2304,2306,2308,2309,2311,2313,2315,2317,2319,2320,2322,2324, 2326,2328,2330,2332,2333,2335,2337,2339,2341,2343,2345,2346,2348,2350,2352,2354, 2356,2358,2359,2361,2363,2365,2367,2369,2371,2372,2374,2376,2378,2380,2382,2384, 2385,2387,2389,2391,2393,2395,2397,2398,2400,2402,2404,2406,2408,2410,2411,2413, 2415,2417,2419,2421,2423,2424,2426,2428,2430,2432,2434,2436,2437,2439,2441,2443, 2445,2447,2449,2450,2452,2454,2456,2458,2460,2462,2463,2465,2467,2469,2471,2473, 2475,2476,2478,2480,2482,2484,2486,2487,2489,2491,2493,2495,2497,2499,2500,2502, 2504,2506,2508,2510,2512,2513,2515,2517,2519,2521,2523,2525,2526,2528,2530,2532, 2534,2536,2538,2539,2541,2543,2545,2547,2549,2551,2552,2554,2556,2558,2560,2562, 2564,2565,2567,2569,2571,2573,2575,2577,2578,2580,2582,2584,2586,2588,2590,2591, 2593,2595,2597,2599,2601,2603,2604,2606,2608,2610,2612,2614,2616,2617,2619,2621, 2623,2625,2627,2629,2630,2632,2634,2636,2638,2640,2641,2643,2645,2647,2649,2651, 2653,2654,2656,2658,2660,2662,2664,2666,2667,2669,2671,2673,2675,2677,2679,2680, 2682,2684,2686,2688,2690,2692,2693,2695,2697,2699,2701,2703,2705,2706,2708,2710, 2712,2714,2716,2718,2719,2721,2723,2725,2727,2729,2731,2732,2734,2736,2738,2740, 2742,2744,2745,2747,2749,2751,2753,2755,2757,2758,2760,2762,2764,2766,2768,2770, 2771,2773,2775,2777,2779,2781,2783,2784,2786,2788,2790,2792,2794,2795,2797,2799, 2801,2803,2805,2807,2808,2810,2812,2814,2816,2818,2820,2821,2823,2825,2827,2829, 2831,2833,2834,2836,2838,2840,2842,2844,2846,2847,2849,2851,2853,2855,2857,2859, 2860,2862,2864,2866,2868,2870,2872,2873,2875,2877,2879,2881,2883,2885,2886,2888, 2890,2892,2894,2896,2898,2899,2901,2903,2905,2907,2909,2911,2912,2914,2916,2918, 2920,2922,2924,2925,2927,2929,2931,2933,2935,2937,2938,2940,2942,2944,2946,2948, 2950,2951,2953,2955,2957,2959,2961,2962,2964,2966,2968,2970,2972,2974,2975,2977, 2979,2981,2983,2985,2987,2988,2990,2992,2994,2996,2998,3000,3001,3003,3005,3007, 3009,3011,3013,3014,3016,3018,3020,3022,3024,3026,3027,3029,3031,3033,3035,3037, 3039,3040,3042,3044,3046,3048,3050,3052,3053,3055,3057,3059,3061,3063,3065,3066, 3068,3070,3072,3074,3076,3078,3079,3081,3083,3085,3087,3089,3091,3092,3094,3096, 3098,3100,3102,3104,3105,3107,3109,3111,3113,3115,3116,3118,3120,3122,3124,3126, 3128,3129,3131,3133,3135,3137,3139,3141,3142,3144,3146,3148,3150,3152,3154,3155, 3157,3159,3161,3163,3165,3167,3168,3170,3172,3174,3176,3178,3180,3181,3183,3185, 3187,3189,3191,3193,3194,3196,3198,3200,3202,3204,3206,3207,3209,3211,3213,3215, 3217,3219,3220,3222,3224,3226,3228,3230,3232,3233,3235,3237,3239,3241,3243,3245, 3246,3248,3250,3252,3254,3256,3258,3259,3261,3263,3265,3267,3269,3270,3272,3274, 3276,3278,3280,3282,3283,3285,3287,3289,3291,3293,3295,3296,3298,3300,3302,3304, 3306,3308,3309,3311,3313,3315,3317,3319,3321,3322,3324,3326,3328,3330,3332,3334, 3335,3337,3339,3341,3343,3345,3347,3348,3350,3352,3354,3356,3358,3360,3361,3363, 3365,3367,3369,3371,3373,3374,3376,3378,3380,3382,3384,3386,3387,3389,3391,3393, 3395,3397,3399,3400,3402,3404,3406,3408,3410,3412,3413,3415,3417,3419,3421,3423, 3425,3426,3428,3430,3432,3434,3436,3437,3439,3441,3443,3445,3447,3449,3450,3452, 3454,3456,3458,3460,3462,3463,3465,3467,3469,3471,3473,3475,3476,3478,3480,3482, 3484,3486,3488,3489,3491,3493,3495,3497,3499,3501,3502,3504,3506,3508,3510,3512, 3514,3515,3517,3519,3521,3523,3525,3527,3528,3530,3532,3534,3536,3538,3540,3541, 3543,3545,3547,3549,3551,3553,3554,3556,3558,3560,3562,3564,3566,3567,3569,3571, 3573,3575,3577,3579,3580,3582,3584,3586,3588,3590,3591,3593,3595,3597,3599,3601, 3603,3604,3606,3608,3610,3612,3614,3616,3617,3619,3621,3623,3625,3627,3629,3630, 3632,3634,3636,3638,3640,3642,3643,3645,3647,3649,3651,3653,3655,3656,3658,3660, 3662,3664,3666,3668,3669,3671,3673,3675,3677,3679,3681,3682,3684,3686,3688,3690, 3692,3694,3695,3697,3699,3701,3703,3705,3707,3708,3710,3712,3714,3716,3718,3720, 3721,3723,3725,3727,3729,3731,3733,3734,3736,3738,3740,3742,3744,3745,3747,3749, 3751,3753,3755,3757,3758,3760,3762,3764,3766,3768,3770,3771,3773,3775,3777,3779, 3781,3783,3784,3786,3788,3790,3792,3794,3796,3797,3799,3801,3803,3805,3807,3809, 3810,3812,3814,3816,3818,3820,3822,3823,3825,3827,3829,3831,3833,3835,3836,3838, 3840,3842,3844,3846,3848,3849,3851,3853,3855,3857,3859,3861,3862,3864,3866,3868, 3870,3872,3874,3875,3877,3879,3881,3883,3885,3887,3888,3890,3892,3894,3896,3898, 3896,3894,3892,3890,3888,3887,3885,3883,3881,3879,3877,3875,3874,3872,3870,3868, 3866,3864,3862,3861,3859,3857,3855,3853,3851,3849,3848,3846,3844,3842,3840,3838, 3836,3835,3833,3831,3829,3827,3825,3823,3822,3820,3818,3816,3814,3812,3810,3809, 3807,3805,3803,3801,3799,3797,3796,3794,3792,3790,3788,3786,3784,3783,3781,3779, 3777,3775,3773,3771,3770,3768,3766,3764,3762,3760,3758,3757,3755,3753,3751,3749, 3747,3745,3744,3742,3740,3738,3736,3734,3733,3731,3729,3727,3725,3723,3721,3720, 3718,3716,3714,3712,3710,3708,3707,3705,3703,3701,3699,3697,3695,3694,3692,3690, 3688,3686,3684,3682,3681,3679,3677,3675,3673,3671,3669,3668,3666,3664,3662,3660, 3658,3656,3655,3653,3651,3649,3647,3645,3643,3642,3640,3638,3636,3634,3632,3630, 3629,3627,3625,3623,3621,3619,3617,3616,3614,3612,3610,3608,3606,3604,3603,3601, 3599,3597,3595,3593,3591,3590,3588,3586,3584,3582,3580,3579,3577,3575,3573,3571, 3569,3567,3566,3564,3562,3560,3558,3556,3554,3553,3551,3549,3547,3545,3543,3541, 3540,3538,3536,3534,3532,3530,3528,3527,3525,3523,3521,3519,3517,3515,3514,3512, 3510,3508,3506,3504,3502,3501,3499,3497,3495,3493,3491,3489,3488,3486,3484,3482, 3480,3478,3476,3475,3473,3471,3469,3467,3465,3463,3462,3460,3458,3456,3454,3452, 3450,3449,3447,3445,3443,3441,3439,3437,3436,3434,3432,3430,3428,3426,3425,3423, 3421,3419,3417,3415,3413,3412,3410,3408,3406,3404,3402,3400,3399,3397,3395,3393, 3391,3389,3387,3386,3384,3382,3380,3378,3376,3374,3373,3371,3369,3367,3365,3363, 3361,3360,3358,3356,3354,3352,3350,3348,3347,3345,3343,3341,3339,3337,3335,3334, 3332,3330,3328,3326,3324,3322,3321,3319,3317,3315,3313,3311,3309,3308,3306,3304, 3302,3300,3298,3296,3295,3293,3291,3289,3287,3285,3283,3282,3280,3278,3276,3274, 3272,3270,3269,3267,3265,3263,3261,3259,3258,3256,3254,3252,3250,3248,3246,3245, 3243,3241,3239,3237,3235,3233,3232,3230,3228,3226,3224,3222,3220,3219,3217,3215, 3213,3211,3209,3207,3206,3204,3202,3200,3198,3196,3194,3193,3191,3189,3187,3185, 3183,3181,3180,3178,3176,3174,3172,3170,3168,3167,3165,3163,3161,3159,3157,3155, 3154,3152,3150,3148,3146,3144,3142,3141,3139,3137,3135,3133,3131,3129,3128,3126, 3124,3122,3120,3118,3116,3115,3113,3111,3109,3107,3105,3104,3102,3100,3098,3096, 3094,3092,3091,3089,3087,3085,3083,3081,3079,3078,3076,3074,3072,3070,3068,3066, 3065,3063,3061,3059,3057,3055,3053,3052,3050,3048,3046,3044,3042,3040,3039,3037, 3035,3033,3031,3029,3027,3026,3024,3022,3020,3018,3016,3014,3013,3011,3009,3007, 3005,3003,3001,3000,2998,2996,2994,2992,2990,2988,2987,2985,2983,2981,2979,2977, 2975,2974,2972,2970,2968,2966,2964,2962,2961,2959,2957,2955,2953,2951,2950,2948, 2946,2944,2942,2940,2938,2937,2935,2933,2931,2929,2927,2925,2924,2922,2920,2918, 2916,2914,2912,2911,2909,2907,2905,2903,2901,2899,2898,2896,2894,2892,2890,2888, 2886,2885,2883,2881,2879,2877,2875,2873,2872,2870,2868,2866,2864,2862,2860,2859, 2857,2855,2853,2851,2849,2847,2846,2844,2842,2840,2838,2836,2834,2833,2831,2829, 2827,2825,2823,2821,2820,2818,2816,2814,2812,2810,2808,2807,2805,2803,2801,2799, 2797,2795,2794,2792,2790,2788,2786,2784,2783,2781,2779,2777,2775,2773,2771,2770, 2768,2766,2764,2762,2760,2758,2757,2755,2753,2751,2749,2747,2745,2744,2742,2740, 2738,2736,2734,2732,2731,2729,2727,2725,2723,2721,2719,2718,2716,2714,2712,2710, 2708,2706,2705,2703,2701,2699,2697,2695,2693,2692,2690,2688,2686,2684,2682,2680, 2679,2677,2675,2673,2671,2669,2667,2666,2664,2662,2660,2658,2656,2654,2653,2651, 2649,2647,2645,2643,2641,2640,2638,2636,2634,2632,2630,2629,2627,2625,2623,2621, 2619,2617,2616,2614,2612,2610,2608,2606,2604,2603,2601,2599,2597,2595,2593,2591, 2590,2588,2586,2584,2582,2580,2578,2577,2575,2573,2571,2569,2567,2565,2564,2562, 2560,2558,2556,2554,2552,2551,2549,2547,2545,2543,2541,2539,2538,2536,2534,2532, 2530,2528,2526,2525,2523,2521,2519,2517,2515,2513,2512,2510,2508,2506,2504,2502, 2500,2499,2497,2495,2493,2491,2489,2487,2486,2484,2482,2480,2478,2476,2475,2473, 2471,2469,2467,2465,2463,2462,2460,2458,2456,2454,2452,2450,2449,2447,2445,2443, 2441,2439,2437,2436,2434,2432,2430,2428,2426,2424,2423,2421,2419,2417,2415,2413, 2411,2410,2408,2406,2404,2402,2400,2398,2397,2395,2393,2391,2389,2387,2385,2384, 2382,2380,2378,2376,2374,2372,2371,2369,2367,2365,2363,2361,2359,2358,2356,2354, 2352,2350,2348,2346,2345,2343,2341,2339,2337,2335,2333,2332,2330,2328,2326,2324, 2322,2320,2319,2317,2315,2313,2311,2309,2308,2306,2304,2302,2300,2298,2296,2295, 2293,2291,2289,2287,2285,2283,2282,2280,2278,2276,2274,2272,2270,2269,2267,2265, 2263,2261,2259,2257,2256,2254,2252,2250,2248,2246,2244,2243,2241,2239,2237,2235, 2233,2231,2230,2228,2226,2224,2222,2220,2218,2217,2215,2213,2211,2209,2207,2205, 2204,2202,2200,2198,2196,2194,2192,2191,2189,2187,2185,2183,2181,2179,2178,2176, 2174,2172,2170,2168,2166,2165,2163,2161,2159,2157,2155,2154,2152,2150,2148,2146, 2144,2142,2141,2139,2137,2135,2133,2131,2129,2128,2126,2124,2122,2120,2118,2116, 2115,2113,2111,2109,2107,2105,2103,2102,2100,2098,2096,2094,2092,2090,2089,2087, 2085,2083,2081,2079,2077,2076,2074,2072,2070,2068,2066,2064,2063,2061,2059,2057, 2055,2053,2051,2050,2048,2046,2044,2042,2040,2038,2037,2035,2033,2031,2029,2027, 2025,2024,2022,2020,2018,2016,2014,2012,2011,2009,2007,2005,2003,2001,2000,1998, 1996,1994,1992,1990,1988,1987,1985,1983,1981,1979,1977,1975,1974,1972,1970,1968, 1966,1964,1962,1961,1959,1957,1955,1953,1951,1949,1948,1946,1944,1942,1940,1938, 1936,1935,1933,1931,1929,1927,1925,1923,1922,1920,1918,1916,1914,1912,1910,1909, 1907,1905,1903,1901,1899,1897,1896,1894,1892,1890,1888,1886,1884,1883,1881,1879, 1877,1875,1873,1871,1870,1868,1866,1864,1862,1860,1858,1857,1855,1853,1851,1849, 1847,1845,1844,1842,1840,1838,1836,1834,1833,1831,1829,1827,1825,1823,1821,1820, 1818,1816,1814,1812,1810,1808,1807,1805,1803,1801,1799,1797,1795,1794,1792,1790, 1788,1786,1784,1782,1781,1779,1777,1775,1773,1771,1769,1768,1766,1764,1762,1760, 1758,1756,1755,1753,1751,1749,1747,1745,1743,1742,1740,1738,1736,1734,1732,1730, 1729,1727,1725,1723,1721,1719,1717,1716,1714,1712,1710,1708,1706,1704,1703,1701, 1699,1697,1695,1693,1691,1690,1688,1686,1684,1682,1680,1679,1677,1675,1673,1671, 1669,1667,1666,1664,1662,1660,1658,1656,1654,1653,1651,1649,1647,1645,1643,1641, 1640,1638,1636,1634,1632,1630,1628,1627,1625,1623,1621,1619,1617,1615,1614,1612, 1610,1608,1606,1604,1602,1601,1599,1597,1595,1593,1591,1589,1588,1586,1584,1582, 1580,1578,1576,1575,1573,1571,1569,1567,1565,1563,1562,1560,1558,1556,1554,1552, 1550,1549,1547,1545,1543,1541,1539,1537,1536,1534,1532,1530,1528,1526,1525,1523, 1521,1519,1517,1515,1513,1512,1510,1508,1506,1504,1502,1500,1499,1497,1495,1493, 1491,1489,1487,1486,1484,1482,1480,1478,1476,1474,1473,1471,1469,1467,1465,1463, 1461,1460,1458,1456,1454,1452,1450,1448,1447,1445,1443,1441,1439,1437,1435,1434, 1432,1430,1428,1426,1424,1422,1421,1419,1417,1415,1413,1411,1409,1408,1406,1404, 1402,1400,1398,1396,1395,1393,1391,1389,1387,1385,1383,1382,1380,1378,1376,1374, 1372,1370,1369,1367,1365,1363,1361,1359,1358,1356,1354,1352,1350,1348,1346,1345, 1343,1341,1339,1337,1335,1333,1332,1330,1328,1326,1324,1322,1320,1319,1317,1315, 1313,1311,1309,1307,1306,1304,1302,1300,1298,1296,1294,1293,1291,1289,1287,1285, 1283,1281,1280,1278,1276,1274,1272,1270,1268,1267,1265,1263,1261,1259,1257,1255, 1254,1252,1250,1248,1246,1244,1242,1241,1239,1237,1235,1233,1231,1229,1228,1226, 1224,1222,1220,1218,1216,1215,1213,1211,1209,1207,1205,1204,1202,1200,1198,1196, 1194,1192,1191,1189,1187,1185,1183,1181,1179,1178,1176,1174,1172,1170,1168,1166, 1165,1163,1161,1159,1157,1155,1153,1152,1150,1148,1146,1144,1142,1140,1139,1137, 1135,1133,1131,1129,1127,1126,1124,1122,1120,1118,1116,1114,1113,1111,1109,1107, 1105,1103,1101,1100,1098,1096,1094,1092,1090,1088,1087,1085,1083,1081,1079,1077, 1075,1074,1072,1070,1068,1066,1064,1062,1061,1059,1057,1055,1053,1051,1050,1048, 1046,1044,1042,1040,1038,1037,1035,1033,1031,1029,1027,1025,1024,1022,1020,1018, 1016,1014,1012,1011,1009,1007,1005,1003,1001,999,998,996,994,992,990,988, 986,985,983,981,979,977,975,973,972,970,968,966,964,962,960,959, 957,955,953,951,949,947,946,944,942,940,938,936,934,933,931,929, 927,925,923,921,920,918,916,914,912,910,908,907,905,903,901,899, 897,895,894,892,890,888,886,884,883,881,879,877,875,873,871,870, 868,866,864,862,860,858,857,855,853,851,849,847,845,844,842,840, 838,836,834,832,831,829,827,825,823,821,819,818,816,814,812,810, 808,806,805,803,801,799,797,795,793,792,790,788,786,784,782,780, 779,777,775,773,771,769,767,766,764,762,760,758,756,754,753,751, 749,747,745,743,741,740,738,736,734,732,730,729,727,725,723,721, 719,717,716,714,712,710,708,706,704,703,701,699,697,695,693,691, 690,688,686,684,682,680,678,677,675,673,671,669,667,665,664,662, 660,658,656,654,652,651,649,647,645,643,641,639,638,636,634,632, 630,628,626,625,623,621,619,617,615,613,612,610,608,606,604,602, 600,599,597,595,593,591,589,587,586,584,582,580,578,576,575,573, 571,569,567,565,563,562,560,558,556,554,552,550,549,547,545,543, 541,539,537,536,534,532,530,528,526,524,523,521,519,517,515,513, 511,510,508,506,504,502,500,498,497,495,493,491,489,487,485,484, 482,480,478,476,474,472,471,469,467,465,463,461,459,458,456,454, 452,450,448,446,445,443,441,439,437,435,433,432,430,428,426,424, 422,420,419,417,415,413,411,409,408,406,404,402,400,398,396,395, 393,391,389,387,385,383,382,380,378,376,374,372,370,369,367,365, 363,361,359,357,356,354,352,350,348,346,344,343,341,339,337,335, 333,331,330,328,326,324,322,320,318,317,315,313,311,309,307,305, 304,302,300,298,296,294,292,291,289,287,285,283,281,279,278,276, 274,272,270,268,266,265,263,261,259,257,255,254,252,250,248,246, 244,242,241,239,237,235,233,231,229,228,226,224,222,220,218,216, 215,213,211,209,207,205,203,202,200,198,196,194,192,190,189,187, 185,183,181,179,177,176,174,172,170,168,166,164,163,161,159,157, 155,153,151,150,148,146,144,142,140,138,137,135,133,131,129,127, 125,124,122,120,118,116,114,112,111,109,107,105,103,101,100,98, 100,101,103,105,107,109,111,112,114,116,118,120,122,124,125,127, 129,131,133,135,137,138,140,142,144,146,148,150,151,153,155,157, 159,161,163,164,166,168,170,172,174,176,177,179,181,183,185,187, 189,190,192,194,196,198,200,202,203,205,207,209,211,213,215,216, 218,220,222,224,226,228,229,231,233,235,237,239,241,242,244,246, 248,250,252,254,255,257,259,261,263,265,266,268,270,272,274,276, 278,279,281,283,285,287,289,291,292,294,296,298,300,302,304,305, 307,309,311,313,315,317,318,320,322,324,326,328,330,331,333,335, 337,339,341,343,344,346,348,350,352,354,356,357,359,361,363,365, 367,369,370,372,374,376,378,380,382,383,385,387,389,391,393,395, 396,398,400,402,404,406,408,409,411,413,415,417,419,420,422,424, 426,428,430,432,433,435,437,439,441,443,445,446,448,450,452,454, 456,458,459,461,463,465,467,469,471,472,474,476,478,480,482,484, 485,487,489,491,493,495,497,498,500,502,504,506,508,510,511,513, 515,517,519,521,523,524,526,528,530,532,534,536,537,539,541,543, 545,547,549,550,552,554,556,558,560,562,563,565,567,569,571,573, 575,576,578,580,582,584,586,587,589,591,593,595,597,599,600,602, 604,606,608,610,612,613,615,617,619,621,623,625,626,628,630,632, 634,636,638,639,641,643,645,647,649,651,652,654,656,658,660,662, 664,665,667,669,671,673,675,677,678,680,682,684,686,688,690,691, 693,695,697,699,701,703,704,706,708,710,712,714,716,717,719,721, 723,725,727,729,730,732,734,736,738,740,741,743,745,747,749,751, 753,754,756,758,760,762,764,766,767,769,771,773,775,777,779,780, 782,784,786,788,790,792,793,795,797,799,801,803,805,806,808,810, 812,814,816,818,819,821,823,825,827,829,831,832,834,836,838,840, 842,844,845,847,849,851,853,855,857,858,860,862,864,866,868,870, 871,873,875,877,879,881,883,884,886,888,890,892,894,895,897,899, 901,903,905,907,908,910,912,914,916,918,920,921,923,925,927,929, 931,933,934,936,938,940,942,944,946,947,949,951,953,955,957,959, 960,962,964,966,968,970,972,973,975,977,979,981,983,985,986,988, 990,992,994,996,998,999,1001,1003,1005,1007,1009,1011,1012,1014,1016,1018, 1020,1022,1024,1025,1027,1029,1031,1033,1035,1037,1038,1040,1042,1044,1046,1048, 1050,1051,1053,1055,1057,1059,1061,1062,1064,1066,1068,1070,1072,1074,1075,1077, 1079,1081,1083,1085,1087,1088,1090,1092,1094,1096,1098,1100,1101,1103,1105,1107, 1109,1111,1113,1114,1116,1118,1120,1122,1124,1126,1127,1129,1131,1133,1135,1137, 1139,1140,1142,1144,1146,1148,1150,1152,1153,1155,1157,1159,1161,1163,1165,1166, 1168,1170,1172,1174,1176,1178,1179,1181,1183,1185,1187,1189,1191,1192,1194,1196, 1198,1200,1202,1204,1205,1207,1209,1211,1213,1215,1216,1218,1220,1222,1224,1226, 1228,1229,1231,1233,1235,1237,1239,1241,1242,1244,1246,1248,1250,1252,1254,1255, 1257,1259,1261,1263,1265,1267,1268,1270,1272,1274,1276,1278,1280,1281,1283,1285, 1287,1289,1291,1293,1294,1296,1298,1300,1302,1304,1306,1307,1309,1311,1313,1315, 1317,1319,1320,1322,1324,1326,1328,1330,1332,1333,1335,1337,1339,1341,1343,1345, 1346,1348,1350,1352,1354,1356,1358,1359,1361,1363,1365,1367,1369,1370,1372,1374, 1376,1378,1380,1382,1383,1385,1387,1389,1391,1393,1395,1396,1398,1400,1402,1404, 1406,1408,1409,1411,1413,1415,1417,1419,1421,1422,1424,1426,1428,1430,1432,1434, 1435,1437,1439,1441,1443,1445,1447,1448,1450,1452,1454,1456,1458,1460,1461,1463, 1465,1467,1469,1471,1473,1474,1476,1478,1480,1482,1484,1486,1487,1489,1491,1493, 1495,1497,1499,1500,1502,1504,1506,1508,1510,1512,1513,1515,1517,1519,1521,1523, 1525,1526,1528,1530,1532,1534,1536,1537,1539,1541,1543,1545,1547,1549,1550,1552, 1554,1556,1558,1560,1562,1563,1565,1567,1569,1571,1573,1575,1576,1578,1580,1582, 1584,1586,1588,1589,1591,1593,1595,1597,1599,1601,1602,1604,1606,1608,1610,1612, 1614,1615,1617,1619,1621,1623,1625,1627,1628,1630,1632,1634,1636,1638,1640,1641, 1643,1645,1647,1649,1651,1653,1654,1656,1658,1660,1662,1664,1666,1667,1669,1671, 1673,1675,1677,1679,1680,1682,1684,1686,1688,1690,1691,1693,1695,1697,1699,1701, 1703,1704,1706,1708,1710,1712,1714,1716,1717,1719,1721,1723,1725,1727,1729,1730, 1732,1734,1736,1738,1740,1742,1743,1745,1747,1749,1751,1753,1755,1756,1758,1760, 1762,1764,1766,1768,1769,1771,1773,1775,1777,1779,1781,1782,1784,1786,1788,1790, 1792,1794,1795,1797,1799,1801,1803,1805,1807,1808,1810,1812,1814,1816,1818,1820, 1821,1823,1825,1827,1829,1831,1833,1834,1836,1838,1840,1842,1844,1845,1847,1849, 1851,1853,1855,1857,1858,1860,1862,1864,1866,1868,1870,1871,1873,1875,1877,1879, 1881,1883,1884,1886,1888,1890,1892,1894,1896,1897,1899,1901,1903,1905,1907,1909, 1910,1912,1914,1916,1918,1920,1922,1923,1925,1927,1929,1931,1933,1935,1936,1938, 1940,1942,1944,1946,1948,1949,1951,1953,1955,1957,1959,1961,1962,1964,1966,1968, 1970,1972,1974,1975,1977,1979,1981,1983,1985,1987,1988,1990,1992,1994,1996,1998 }; const unsigned short sawtable[1]={98}; const unsigned short SineTable[4096] = { 2000,2003,2006,2009,2012,2015,2017,2020,2023,2026,2029,2032,2035,2038,2041,2044,2047,2050,2052,2055,2058,2061,2064,2067,2070,2073,2076,2079,2082,2084,2087,2090, 2093,2096,2099,2102,2105,2108,2111,2114,2117,2119,2122,2125,2128,2131,2134,2137,2140,2143,2146,2148,2151,2154,2157,2160,2163,2166,2169,2172,2175,2178,2180,2183, 2186,2189,2192,2195,2198,2201,2204,2207,2209,2212,2215,2218,2221,2224,2227,2230,2233,2235,2238,2241,2244,2247,2250,2253,2256,2259,2261,2264,2267,2270,2273,2276, 2279,2282,2285,2287,2290,2293,2296,2299,2302,2305,2308,2310,2313,2316,2319,2322,2325,2328,2331,2333,2336,2339,2342,2345,2348,2351,2354,2356,2359,2362,2365,2368, 2371,2374,2376,2379,2382,2385,2388,2391,2394,2396,2399,2402,2405,2408,2411,2413,2416,2419,2422,2425,2428,2430,2433,2436,2439,2442,2445,2448,2450,2453,2456,2459, 2462,2464,2467,2470,2473,2476,2479,2481,2484,2487,2490,2493,2496,2498,2501,2504,2507,2510,2512,2515,2518,2521,2524,2526,2529,2532,2535,2538,2540,2543,2546,2549, 2552,2554,2557,2560,2563,2565,2568,2571,2574,2577,2579,2582,2585,2588,2590,2593,2596,2599,2602,2604,2607,2610,2613,2615,2618,2621,2624,2626,2629,2632,2635,2637, 2640,2643,2646,2648,2651,2654,2657,2659,2662,2665,2667,2670,2673,2676,2678,2681,2684,2687,2689,2692,2695,2697,2700,2703,2706,2708,2711,2714,2716,2719,2722,2724, 2727,2730,2732,2735,2738,2741,2743,2746,2749,2751,2754,2757,2759,2762,2765,2767,2770,2773,2775,2778,2781,2783,2786,2789,2791,2794,2797,2799,2802,2804,2807,2810, 2812,2815,2818,2820,2823,2826,2828,2831,2833,2836,2839,2841,2844,2846,2849,2852,2854,2857,2859,2862,2865,2867,2870,2872,2875,2878,2880,2883,2885,2888,2891,2893, 2896,2898,2901,2903,2906,2908,2911,2914,2916,2919,2921,2924,2926,2929,2931,2934,2937,2939,2942,2944,2947,2949,2952,2954,2957,2959,2962,2964,2967,2969,2972,2974, 2977,2979,2982,2984,2987,2989,2992,2994,2997,2999,3002,3004,3007,3009,3012,3014,3016,3019,3021,3024,3026,3029,3031,3034,3036,3039,3041,3043,3046,3048,3051,3053, 3056,3058,3060,3063,3065,3068,3070,3072,3075,3077,3080,3082,3084,3087,3089,3092,3094,3096,3099,3101,3104,3106,3108,3111,3113,3115,3118,3120,3122,3125,3127,3129, 3132,3134,3137,3139,3141,3144,3146,3148,3150,3153,3155,3157,3160,3162,3164,3167,3169,3171,3174,3176,3178,3180,3183,3185,3187,3190,3192,3194,3196,3199,3201,3203, 3205,3208,3210,3212,3214,3217,3219,3221,3223,3226,3228,3230,3232,3234,3237,3239,3241,3243,3245,3248,3250,3252,3254,3256,3259,3261,3263,3265,3267,3269,3272,3274, 3276,3278,3280,3282,3285,3287,3289,3291,3293,3295,3297,3300,3302,3304,3306,3308,3310,3312,3314,3316,3319,3321,3323,3325,3327,3329,3331,3333,3335,3337,3339,3341, 3344,3346,3348,3350,3352,3354,3356,3358,3360,3362,3364,3366,3368,3370,3372,3374,3376,3378,3380,3382,3384,3386,3388,3390,3392,3394,3396,3398,3400,3402,3404,3406, 3408,3410,3412,3414,3416,3418,3419,3421,3423,3425,3427,3429,3431,3433,3435,3437,3439,3441,3442,3444,3446,3448,3450,3452,3454,3456,3458,3459,3461,3463,3465,3467, 3469,3471,3472,3474,3476,3478,3480,3482,3483,3485,3487,3489,3491,3492,3494,3496,3498,3500,3501,3503,3505,3507,3509,3510,3512,3514,3516,3517,3519,3521,3523,3524, 3526,3528,3530,3531,3533,3535,3536,3538,3540,3542,3543,3545,3547,3548,3550,3552,3553,3555,3557,3558,3560,3562,3563,3565,3567,3568,3570,3572,3573,3575,3577,3578, 3580,3581,3583,3585,3586,3588,3589,3591,3593,3594,3596,3597,3599,3601,3602,3604,3605,3607,3608,3610,3611,3613,3615,3616,3618,3619,3621,3622,3624,3625,3627,3628, 3630,3631,3633,3634,3636,3637,3639,3640,3642,3643,3644,3646,3647,3649,3650,3652,3653,3655,3656,3657,3659,3660,3662,3663,3665,3666,3667,3669,3670,3672,3673,3674, 3676,3677,3678,3680,3681,3682,3684,3685,3687,3688,3689,3691,3692,3693,3694,3696,3697,3698,3700,3701,3702,3704,3705,3706,3707,3709,3710,3711,3713,3714,3715,3716, 3718,3719,3720,3721,3723,3724,3725,3726,3727,3729,3730,3731,3732,3733,3735,3736,3737,3738,3739,3741,3742,3743,3744,3745,3746,3747,3749,3750,3751,3752,3753,3754, 3755,3756,3758,3759,3760,3761,3762,3763,3764,3765,3766,3767,3768,3770,3771,3772,3773,3774,3775,3776,3777,3778,3779,3780,3781,3782,3783,3784,3785,3786,3787,3788, 3789,3790,3791,3792,3793,3794,3795,3796,3797,3798,3799,3799,3800,3801,3802,3803,3804,3805,3806,3807,3808,3809,3810,3810,3811,3812,3813,3814,3815,3816,3816,3817, 3818,3819,3820,3821,3822,3822,3823,3824,3825,3826,3826,3827,3828,3829,3830,3830,3831,3832,3833,3833,3834,3835,3836,3837,3837,3838,3839,3839,3840,3841,3842,3842, 3843,3844,3844,3845,3846,3847,3847,3848,3849,3849,3850,3851,3851,3852,3853,3853,3854,3854,3855,3856,3856,3857,3858,3858,3859,3859,3860,3861,3861,3862,3862,3863, 3863,3864,3865,3865,3866,3866,3867,3867,3868,3868,3869,3869,3870,3871,3871,3872,3872,3873,3873,3874,3874,3874,3875,3875,3876,3876,3877,3877,3878,3878,3879,3879, 3879,3880,3880,3881,3881,3882,3882,3882,3883,3883,3883,3884,3884,3885,3885,3885,3886,3886,3886,3887,3887,3887,3888,3888,3888,3889,3889,3889,3890,3890,3890,3891, 3891,3891,3891,3892,3892,3892,3892,3893,3893,3893,3893,3894,3894,3894,3894,3895,3895,3895,3895,3895,3896,3896,3896,3896,3896,3897,3897,3897,3897,3897,3897,3898, 3898,3898,3898,3898,3898,3898,3898,3899,3899,3899,3899,3899,3899,3899,3899,3899,3899,3899,3900,3900,3900,3900,3900,3900,3900,3900,3900,3900,3900,3900,3900,3900, 3900,3900,3900,3900,3900,3900,3900,3900,3900,3900,3900,3900,3900,3900,3900,3899,3899,3899,3899,3899,3899,3899,3899,3899,3899,3899,3898,3898,3898,3898,3898,3898, 3898,3898,3897,3897,3897,3897,3897,3897,3896,3896,3896,3896,3896,3895,3895,3895,3895,3895,3894,3894,3894,3894,3893,3893,3893,3893,3892,3892,3892,3892,3891,3891, 3891,3891,3890,3890,3890,3889,3889,3889,3888,3888,3888,3887,3887,3887,3886,3886,3886,3885,3885,3885,3884,3884,3883,3883,3883,3882,3882,3882,3881,3881,3880,3880, 3879,3879,3879,3878,3878,3877,3877,3876,3876,3875,3875,3874,3874,3874,3873,3873,3872,3872,3871,3871,3870,3869,3869,3868,3868,3867,3867,3866,3866,3865,3865,3864, 3863,3863,3862,3862,3861,3861,3860,3859,3859,3858,3858,3857,3856,3856,3855,3854,3854,3853,3853,3852,3851,3851,3850,3849,3849,3848,3847,3847,3846,3845,3844,3844, 3843,3842,3842,3841,3840,3839,3839,3838,3837,3837,3836,3835,3834,3833,3833,3832,3831,3830,3830,3829,3828,3827,3826,3826,3825,3824,3823,3822,3822,3821,3820,3819, 3818,3817,3816,3816,3815,3814,3813,3812,3811,3810,3810,3809,3808,3807,3806,3805,3804,3803,3802,3801,3800,3799,3799,3798,3797,3796,3795,3794,3793,3792,3791,3790, 3789,3788,3787,3786,3785,3784,3783,3782,3781,3780,3779,3778,3777,3776,3775,3774,3773,3772,3771,3770,3768,3767,3766,3765,3764,3763,3762,3761,3760,3759,3758,3756, 3755,3754,3753,3752,3751,3750,3749,3747,3746,3745,3744,3743,3742,3741,3739,3738,3737,3736,3735,3733,3732,3731,3730,3729,3727,3726,3725,3724,3723,3721,3720,3719, 3718,3716,3715,3714,3713,3711,3710,3709,3707,3706,3705,3704,3702,3701,3700,3698,3697,3696,3694,3693,3692,3691,3689,3688,3687,3685,3684,3682,3681,3680,3678,3677, 3676,3674,3673,3672,3670,3669,3667,3666,3665,3663,3662,3660,3659,3657,3656,3655,3653,3652,3650,3649,3647,3646,3644,3643,3642,3640,3639,3637,3636,3634,3633,3631, 3630,3628,3627,3625,3624,3622,3621,3619,3618,3616,3615,3613,3611,3610,3608,3607,3605,3604,3602,3601,3599,3597,3596,3594,3593,3591,3589,3588,3586,3585,3583,3581, 3580,3578,3577,3575,3573,3572,3570,3568,3567,3565,3563,3562,3560,3558,3557,3555,3553,3552,3550,3548,3547,3545,3543,3542,3540,3538,3536,3535,3533,3531,3530,3528, 3526,3524,3523,3521,3519,3517,3516,3514,3512,3510,3509,3507,3505,3503,3501,3500,3498,3496,3494,3492,3491,3489,3487,3485,3483,3482,3480,3478,3476,3474,3472,3471, 3469,3467,3465,3463,3461,3459,3458,3456,3454,3452,3450,3448,3446,3444,3442,3441,3439,3437,3435,3433,3431,3429,3427,3425,3423,3421,3419,3418,3416,3414,3412,3410, 3408,3406,3404,3402,3400,3398,3396,3394,3392,3390,3388,3386,3384,3382,3380,3378,3376,3374,3372,3370,3368,3366,3364,3362,3360,3358,3356,3354,3352,3350,3348,3346, 3344,3341,3339,3337,3335,3333,3331,3329,3327,3325,3323,3321,3319,3316,3314,3312,3310,3308,3306,3304,3302,3300,3297,3295,3293,3291,3289,3287,3285,3282,3280,3278, 3276,3274,3272,3269,3267,3265,3263,3261,3259,3256,3254,3252,3250,3248,3245,3243,3241,3239,3237,3234,3232,3230,3228,3226,3223,3221,3219,3217,3214,3212,3210,3208, 3205,3203,3201,3199,3196,3194,3192,3190,3187,3185,3183,3180,3178,3176,3174,3171,3169,3167,3164,3162,3160,3157,3155,3153,3150,3148,3146,3144,3141,3139,3137,3134, 3132,3129,3127,3125,3122,3120,3118,3115,3113,3111,3108,3106,3104,3101,3099,3096,3094,3092,3089,3087,3084,3082,3080,3077,3075,3072,3070,3068,3065,3063,3060,3058, 3056,3053,3051,3048,3046,3043,3041,3039,3036,3034,3031,3029,3026,3024,3021,3019,3016,3014,3012,3009,3007,3004,3002,2999,2997,2994,2992,2989,2987,2984,2982,2979, 2977,2974,2972,2969,2967,2964,2962,2959,2957,2954,2952,2949,2947,2944,2942,2939,2937,2934,2931,2929,2926,2924,2921,2919,2916,2914,2911,2908,2906,2903,2901,2898, 2896,2893,2891,2888,2885,2883,2880,2878,2875,2872,2870,2867,2865,2862,2859,2857,2854,2852,2849,2846,2844,2841,2839,2836,2833,2831,2828,2826,2823,2820,2818,2815, 2812,2810,2807,2804,2802,2799,2797,2794,2791,2789,2786,2783,2781,2778,2775,2773,2770,2767,2765,2762,2759,2757,2754,2751,2749,2746,2743,2741,2738,2735,2732,2730, 2727,2724,2722,2719,2716,2714,2711,2708,2706,2703,2700,2697,2695,2692,2689,2687,2684,2681,2678,2676,2673,2670,2667,2665,2662,2659,2657,2654,2651,2648,2646,2643, 2640,2637,2635,2632,2629,2626,2624,2621,2618,2615,2613,2610,2607,2604,2602,2599,2596,2593,2590,2588,2585,2582,2579,2577,2574,2571,2568,2565,2563,2560,2557,2554, 2552,2549,2546,2543,2540,2538,2535,2532,2529,2526,2524,2521,2518,2515,2512,2510,2507,2504,2501,2498,2496,2493,2490,2487,2484,2481,2479,2476,2473,2470,2467,2464, 2462,2459,2456,2453,2450,2448,2445,2442,2439,2436,2433,2430,2428,2425,2422,2419,2416,2413,2411,2408,2405,2402,2399,2396,2394,2391,2388,2385,2382,2379,2376,2374, 2371,2368,2365,2362,2359,2356,2354,2351,2348,2345,2342,2339,2336,2333,2331,2328,2325,2322,2319,2316,2313,2310,2308,2305,2302,2299,2296,2293,2290,2287,2285,2282, 2279,2276,2273,2270,2267,2264,2261,2259,2256,2253,2250,2247,2244,2241,2238,2235,2233,2230,2227,2224,2221,2218,2215,2212,2209,2207,2204,2201,2198,2195,2192,2189, 2186,2183,2180,2178,2175,2172,2169,2166,2163,2160,2157,2154,2151,2148,2146,2143,2140,2137,2134,2131,2128,2125,2122,2119,2117,2114,2111,2108,2105,2102,2099,2096, 2093,2090,2087,2084,2082,2079,2076,2073,2070,2067,2064,2061,2058,2055,2052,2050,2047,2044,2041,2038,2035,2032,2029,2026,2023,2020,2017,2015,2012,2009,2006,2003, 2000,1997,1994,1991,1988,1985,1983,1980,1977,1974,1971,1968,1965,1962,1959,1956,1953,1950,1948,1945,1942,1939,1936,1933,1930,1927,1924,1921,1918,1916,1913,1910, 1907,1904,1901,1898,1895,1892,1889,1886,1883,1881,1878,1875,1872,1869,1866,1863,1860,1857,1854,1852,1849,1846,1843,1840,1837,1834,1831,1828,1825,1822,1820,1817, 1814,1811,1808,1805,1802,1799,1796,1793,1791,1788,1785,1782,1779,1776,1773,1770,1767,1765,1762,1759,1756,1753,1750,1747,1744,1741,1739,1736,1733,1730,1727,1724, 1721,1718,1715,1713,1710,1707,1704,1701,1698,1695,1692,1690,1687,1684,1681,1678,1675,1672,1669,1667,1664,1661,1658,1655,1652,1649,1646,1644,1641,1638,1635,1632, 1629,1626,1624,1621,1618,1615,1612,1609,1606,1604,1601,1598,1595,1592,1589,1587,1584,1581,1578,1575,1572,1570,1567,1564,1561,1558,1555,1552,1550,1547,1544,1541, 1538,1536,1533,1530,1527,1524,1521,1519,1516,1513,1510,1507,1504,1502,1499,1496,1493,1490,1488,1485,1482,1479,1476,1474,1471,1468,1465,1462,1460,1457,1454,1451, 1448,1446,1443,1440,1437,1435,1432,1429,1426,1423,1421,1418,1415,1412,1410,1407,1404,1401,1398,1396,1393,1390,1387,1385,1382,1379,1376,1374,1371,1368,1365,1363, 1360,1357,1354,1352,1349,1346,1343,1341,1338,1335,1333,1330,1327,1324,1322,1319,1316,1313,1311,1308,1305,1303,1300,1297,1294,1292,1289,1286,1284,1281,1278,1276, 1273,1270,1268,1265,1262,1259,1257,1254,1251,1249,1246,1243,1241,1238,1235,1233,1230,1227,1225,1222,1219,1217,1214,1211,1209,1206,1203,1201,1198,1196,1193,1190, 1188,1185,1182,1180,1177,1174,1172,1169,1167,1164,1161,1159,1156,1154,1151,1148,1146,1143,1141,1138,1135,1133,1130,1128,1125,1122,1120,1117,1115,1112,1109,1107, 1104,1102,1099,1097,1094,1092,1089,1086,1084,1081,1079,1076,1074,1071,1069,1066,1063,1061,1058,1056,1053,1051,1048,1046,1043,1041,1038,1036,1033,1031,1028,1026, 1023,1021,1018,1016,1013,1011,1008,1006,1003,1001,998,996,993,991,988,986,984,981,979,976,974,971,969,966,964,961,959,957,954,952,949,947, 944,942,940,937,935,932,930,928,925,923,920,918,916,913,911,908,906,904,901,899,896,894,892,889,887,885,882,880,878,875,873,871, 868,866,863,861,859,856,854,852,850,847,845,843,840,838,836,833,831,829,826,824,822,820,817,815,813,810,808,806,804,801,799,797, 795,792,790,788,786,783,781,779,777,774,772,770,768,766,763,761,759,757,755,752,750,748,746,744,741,739,737,735,733,731,728,726, 724,722,720,718,715,713,711,709,707,705,703,700,698,696,694,692,690,688,686,684,681,679,677,675,673,671,669,667,665,663,661,659, 656,654,652,650,648,646,644,642,640,638,636,634,632,630,628,626,624,622,620,618,616,614,612,610,608,606,604,602,600,598,596,594, 592,590,588,586,584,582,581,579,577,575,573,571,569,567,565,563,561,559,558,556,554,552,550,548,546,544,542,541,539,537,535,533, 531,529,528,526,524,522,520,518,517,515,513,511,509,508,506,504,502,500,499,497,495,493,491,490,488,486,484,483,481,479,477,476, 474,472,470,469,467,465,464,462,460,458,457,455,453,452,450,448,447,445,443,442,440,438,437,435,433,432,430,428,427,425,423,422, 420,419,417,415,414,412,411,409,407,406,404,403,401,399,398,396,395,393,392,390,389,387,385,384,382,381,379,378,376,375,373,372, 370,369,367,366,364,363,361,360,358,357,356,354,353,351,350,348,347,345,344,343,341,340,338,337,335,334,333,331,330,328,327,326, 324,323,322,320,319,318,316,315,313,312,311,309,308,307,306,304,303,302,300,299,298,296,295,294,293,291,290,289,287,286,285,284, 282,281,280,279,277,276,275,274,273,271,270,269,268,267,265,264,263,262,261,259,258,257,256,255,254,253,251,250,249,248,247,246, 245,244,242,241,240,239,238,237,236,235,234,233,232,230,229,228,227,226,225,224,223,222,221,220,219,218,217,216,215,214,213,212, 211,210,209,208,207,206,205,204,203,202,201,201,200,199,198,197,196,195,194,193,192,191,190,190,189,188,187,186,185,184,184,183, 182,181,180,179,178,178,177,176,175,174,174,173,172,171,170,170,169,168,167,167,166,165,164,163,163,162,161,161,160,159,158,158, 157,156,156,155,154,153,153,152,151,151,150,149,149,148,147,147,146,146,145,144,144,143,142,142,141,141,140,139,139,138,138,137, 137,136,135,135,134,134,133,133,132,132,131,131,130,129,129,128,128,127,127,126,126,126,125,125,124,124,123,123,122,122,121,121, 121,120,120,119,119,118,118,118,117,117,117,116,116,115,115,115,114,114,114,113,113,113,112,112,112,111,111,111,110,110,110,109, 109,109,109,108,108,108,108,107,107,107,107,106,106,106,106,105,105,105,105,105,104,104,104,104,104,103,103,103,103,103,103,102, 102,102,102,102,102,102,102,101,101,101,101,101,101,101,101,101,101,101,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,101,101,101,101,101,101,101,101,101,101,101,102,102,102,102,102,102, 102,102,103,103,103,103,103,103,104,104,104,104,104,105,105,105,105,105,106,106,106,106,107,107,107,107,108,108,108,108,109,109, 109,109,110,110,110,111,111,111,112,112,112,113,113,113,114,114,114,115,115,115,116,116,117,117,117,118,118,118,119,119,120,120, 121,121,121,122,122,123,123,124,124,125,125,126,126,126,127,127,128,128,129,129,130,131,131,132,132,133,133,134,134,135,135,136, 137,137,138,138,139,139,140,141,141,142,142,143,144,144,145,146,146,147,147,148,149,149,150,151,151,152,153,153,154,155,156,156, 157,158,158,159,160,161,161,162,163,163,164,165,166,167,167,168,169,170,170,171,172,173,174,174,175,176,177,178,178,179,180,181, 182,183,184,184,185,186,187,188,189,190,190,191,192,193,194,195,196,197,198,199,200,201,201,202,203,204,205,206,207,208,209,210, 211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,232,233,234,235,236,237,238,239,240,241,242,244, 245,246,247,248,249,250,251,253,254,255,256,257,258,259,261,262,263,264,265,267,268,269,270,271,273,274,275,276,277,279,280,281, 282,284,285,286,287,289,290,291,293,294,295,296,298,299,300,302,303,304,306,307,308,309,311,312,313,315,316,318,319,320,322,323, 324,326,327,328,330,331,333,334,335,337,338,340,341,343,344,345,347,348,350,351,353,354,356,357,358,360,361,363,364,366,367,369, 370,372,373,375,376,378,379,381,382,384,385,387,389,390,392,393,395,396,398,399,401,403,404,406,407,409,411,412,414,415,417,419, 420,422,423,425,427,428,430,432,433,435,437,438,440,442,443,445,447,448,450,452,453,455,457,458,460,462,464,465,467,469,470,472, 474,476,477,479,481,483,484,486,488,490,491,493,495,497,499,500,502,504,506,508,509,511,513,515,517,518,520,522,524,526,528,529, 531,533,535,537,539,541,542,544,546,548,550,552,554,556,558,559,561,563,565,567,569,571,573,575,577,579,581,582,584,586,588,590, 592,594,596,598,600,602,604,606,608,610,612,614,616,618,620,622,624,626,628,630,632,634,636,638,640,642,644,646,648,650,652,654, 656,659,661,663,665,667,669,671,673,675,677,679,681,684,686,688,690,692,694,696,698,700,703,705,707,709,711,713,715,718,720,722, 724,726,728,731,733,735,737,739,741,744,746,748,750,752,755,757,759,761,763,766,768,770,772,774,777,779,781,783,786,788,790,792, 795,797,799,801,804,806,808,810,813,815,817,820,822,824,826,829,831,833,836,838,840,843,845,847,850,852,854,856,859,861,863,866, 868,871,873,875,878,880,882,885,887,889,892,894,896,899,901,904,906,908,911,913,916,918,920,923,925,928,930,932,935,937,940,942, 944,947,949,952,954,957,959,961,964,966,969,971,974,976,979,981,984,986,988,991,993,996,998,1001,1003,1006,1008,1011,1013,1016,1018,1021, 1023,1026,1028,1031,1033,1036,1038,1041,1043,1046,1048,1051,1053,1056,1058,1061,1063,1066,1069,1071,1074,1076,1079,1081,1084,1086,1089,1092,1094,1097,1099,1102, 1104,1107,1109,1112,1115,1117,1120,1122,1125,1128,1130,1133,1135,1138,1141,1143,1146,1148,1151,1154,1156,1159,1161,1164,1167,1169,1172,1174,1177,1180,1182,1185, 1188,1190,1193,1196,1198,1201,1203,1206,1209,1211,1214,1217,1219,1222,1225,1227,1230,1233,1235,1238,1241,1243,1246,1249,1251,1254,1257,1259,1262,1265,1268,1270, 1273,1276,1278,1281,1284,1286,1289,1292,1294,1297,1300,1303,1305,1308,1311,1313,1316,1319,1322,1324,1327,1330,1333,1335,1338,1341,1343,1346,1349,1352,1354,1357, 1360,1363,1365,1368,1371,1374,1376,1379,1382,1385,1387,1390,1393,1396,1398,1401,1404,1407,1410,1412,1415,1418,1421,1423,1426,1429,1432,1435,1437,1440,1443,1446, 1448,1451,1454,1457,1460,1462,1465,1468,1471,1474,1476,1479,1482,1485,1488,1490,1493,1496,1499,1502,1504,1507,1510,1513,1516,1519,1521,1524,1527,1530,1533,1536, 1538,1541,1544,1547,1550,1552,1555,1558,1561,1564,1567,1570,1572,1575,1578,1581,1584,1587,1589,1592,1595,1598,1601,1604,1606,1609,1612,1615,1618,1621,1624,1626, 1629,1632,1635,1638,1641,1644,1646,1649,1652,1655,1658,1661,1664,1667,1669,1672,1675,1678,1681,1684,1687,1690,1692,1695,1698,1701,1704,1707,1710,1713,1715,1718, 1721,1724,1727,1730,1733,1736,1739,1741,1744,1747,1750,1753,1756,1759,1762,1765,1767,1770,1773,1776,1779,1782,1785,1788,1791,1793,1796,1799,1802,1805,1808,1811, 1814,1817,1820,1822,1825,1828,1831,1834,1837,1840,1843,1846,1849,1852,1854,1857,1860,1863,1866,1869,1872,1875,1878,1881,1883,1886,1889,1892,1895,1898,1901,1904, 1907,1910,1913,1916,1918,1921,1924,1927,1930,1933,1936,1939,1942,1945,1948,1950,1953,1956,1959,1962,1965,1968,1971,1974,1977,1980,1983,1985,1988,1991,1994,1997 }; const char wavheader[44]={0x52,0x49,0x46,0x46, 0xFF,0xFF,0xFF,0xFF, 0x57,0x41,0x56,0x45, 0x66,0x6d,0x74,0x20, 0x10,0x00,0x00,0x00, 0x01,0x00, 0x02,0x00, 0x80,0x3E,0x00,0x00, 0x0,0xFA,0x00,0x00, 0x04,0x00, 0x10,0x00, 0x64,0x61,0x74,0x61, 0xFF,0xFF,0xFF,0xFF}; const char toneheader[44]={0x52,0x49,0x46,0x46, 0xFF,0xFF,0xFF,0xFF, 0x57,0x41,0x56,0x45, 0x66,0x6d,0x74,0x20, 0x10,0x00,0x00,0x00, 0x01,0x00, 0x02,0x00, 0x44,0xAC,0x00,0x00, 0x10,0xB1,0x02,0x00, 0x04,0x00, 0x10,0x00, 0x64,0x61,0x74,0x61, 0xFF,0xFF,0xFF,0xFF}; void __not_in_flash_func(iconvert)(uint16_t *ibuff, int16_t *sbuff, int count){ int i; for(i=0;i<(count);i+=2){ ibuff[i]=(uint16_t)((((int)sbuff[i]*mapping[vol_left]/2000+32768))>>4); ibuff[i+1]=(uint16_t)((((int)sbuff[i+1]*mapping[vol_right]/2000+32768))>>4); } } void MIPS64 __not_in_flash_func(i2sconvert)(int16_t *fbuff, int16_t *sbuff, int count){ int i; for(i=0;i<(count);i+=2){ sbuff[i]=(int16_t)((int)(fbuff[i])*mapping[vol_left]/2000); sbuff[i+1]=(int32_t)((int)(fbuff[i+1])*mapping[vol_right]/2000); } } size_t onRead(void *userdata, char *pBufferOut, size_t bytesToRead){ unsigned int nbr; if(filesource[WAV_fnbr]==FATFSFILE){ FSerror=f_read(FileTable[WAV_fnbr].fptr,pBufferOut, bytesToRead, &nbr); if(FSerror)nbr=0; if(!MDD_SDSPI_CardDetectState())ErrorCheck(WAV_fnbr); } else { nbr=lfs_file_read(&lfs, FileTable[WAV_fnbr].lfsptr, pBufferOut, bytesToRead); if(nbr<0)FSerror=nbr; else FSerror=0; ErrorCheck(WAV_fnbr); } return nbr; } drwav_bool32 onSeek(void *userdata, int offset, drwav_seek_origin origin){ if(filesource[WAV_fnbr]==FATFSFILE){ if(origin==drwav_seek_origin_start) FSerror=f_lseek(FileTable[WAV_fnbr].fptr,offset); else FSerror=f_lseek(FileTable[WAV_fnbr].fptr,FileTable[WAV_fnbr].fptr->fptr+offset); } else { if(origin==drwav_seek_origin_start) FSerror=lfs_file_seek(&lfs, FileTable[WAV_fnbr].lfsptr, offset, LFS_SEEK_SET); else FSerror=lfs_file_seek(&lfs, FileTable[WAV_fnbr].lfsptr, offset, LFS_SEEK_CUR); } return 1; } /*drwav_bool32 onTell(void *userdata, drwav_int64* pCursor){ if(filesource[WAV_fnbr]==FATFSFILE){ *pCursor=(*(FileTable[WAV_fnbr].fptr)).fptr; } else { *pCursor=lfs_file_tell(&lfs,FileTable[WAV_fnbr].lfsptr); } return 1; }*/ void CloseAudio(int all){ #ifdef rp2350 if(!PSRAMsize) #endif modbuff = (Option.modbuff ? (char *)(XIP_BASE + RoundUpK4(TOP_OF_SYSTEM_FLASH)) : NULL); int was_playing=CurrentlyPlaying; if(!Option.audio_i2s_bclk){ bcount[1] = bcount[2] = wav_filesize = 0; swingbuf = nextbuf = playreadcomplete = 0; } StopAudio(); if(CurrentlyPlaying==P_WAVOPEN)CurrentlyPlaying=P_NOTHING; ForceFileClose(WAV_fnbr); FreeMemorySafe((void **)&sbuff1); FreeMemorySafe((void **)&sbuff2); FreeMemorySafe((void **)&noisetable); //FreeMemorySafe((void **)&usertable); usertable=NULL; FreeMemorySafe((void **)&mcontext); if(all){ FreeMemorySafe((void **)&alist); trackstoplay=0; trackplaying=0; } memset(WAVfilename,0,sizeof(WAVfilename)); WAVcomplete = true; FSerror = 0; if(was_playing == P_FLAC || was_playing == P_PAUSE_FLAC )FreeMemorySafe((void **)&myflac); if(was_playing == P_WAV || was_playing == P_PAUSE_WAV )FreeMemorySafe((void **)&mywav); #ifdef rp2350 if((was_playing == P_MP3 || was_playing == P_PAUSE_MP3 ) && (Option.AUDIO_L || Option.audio_i2s_bclk || Option.AUDIO_MOSI_PIN)){ drmp3_uninit(mymp3); FreeMemorySafe((void **)&mymp3); } if(PSRAMsize && was_playing == P_MOD)FreeMemorySafe((void **)&modbuff); #endif int i; for(i=0;i>1)*4000)/4096),(int)(((AUDIO_WRAP>>1)*4000)/4096)); } pwm_clear_irq(AUDIO_SLICE); if(Option.audio_i2s_bclk){ float clockdiv=(Option.CPU_Speed*1000.0f)/(float)(rate*128); pio_sm_set_clkdiv(pioi2s,i2ssm,clockdiv); } } void playvs1053(int mode){ XCS=PinDef[Option.AUDIO_CS_PIN].GPno; XDCS=PinDef[Option.AUDIO_DCS_PIN].GPno; DREQ=PinDef[Option.AUDIO_DREQ_PIN].GPno; XRST=PinDef[Option.AUDIO_RESET_PIN].GPno; VS1053(XCS,XDCS,DREQ,XRST); switchToMp3Mode(); loadDefaultVs1053Patches(); setVolumes(vol_left,vol_right); //playing a file setrate(6000); //32KHz should be fast enough if(mode==P_MOD){ memcpy((char *)sbuff1,wavheader,sizeof(wavheader)); bcount[1]=44; wav_filesize=bcount[1]; } else { sbuff1 = GetMemory(WAV_BUFFER_SIZE); sbuff2 = GetMemory(WAV_BUFFER_SIZE); bcount[1]=onRead(NULL,sbuff1,WAV_BUFFER_SIZE); wav_filesize=bcount[1]; } CurrentlyPlaying = mode; swingbuf=1; nextbuf=2; ppos=0; playreadcomplete=0; pwm_set_irq0_enabled(AUDIO_SLICE, true); pwm_set_enabled(AUDIO_SLICE, true); uint64_t t=time_us_64(); uSec(25); while(1){ //read all the headers without stalling checkWAVinput(); uSec(25); if(time_us_64()-t>500000)break; } } void playimmediatevs1053(int play){ if(CurrentlyPlaying==P_WAVOPEN)return; XCS=PinDef[Option.AUDIO_CS_PIN].GPno; XDCS=PinDef[Option.AUDIO_DCS_PIN].GPno; DREQ=PinDef[Option.AUDIO_DREQ_PIN].GPno; XRST=PinDef[Option.AUDIO_RESET_PIN].GPno; VS1053(XCS,XDCS,DREQ,XRST); switchToMp3Mode(); loadDefaultVs1053Patches(); setVolumes(vol_left,vol_right); //playing a file setrate(PWM_FREQ); //16KHz should be fast enough CurrentlyPlaying = play; playChunk((uint8_t *)toneheader,sizeof(toneheader)); } void wavcallback(char *p){ int actualrate; if(strchr((char *)p, '.') == NULL) strcat((char *)p, ".wav"); if(CurrentlyPlaying == P_WAV){ CloseAudio(0); } WAV_fnbr = FindFreeFileNbr(); if(!BasicFileOpen(p, WAV_fnbr, FA_READ)) return; strcpy(WAVfilename,p); if(Option.AUDIO_MISO_PIN){ playvs1053(P_WAV); return; } drwav_allocation_callbacks allocationCallbacks; allocationCallbacks.pUserData = NULL; allocationCallbacks.onMalloc = my_malloc; allocationCallbacks.onRealloc = NULL; allocationCallbacks.onFree = my_free; mywav=GetMemory(sizeof(drwav)); drwav_init(mywav,(drwav_read_proc)onRead, (drwav_seek_proc)onSeek, NULL, &allocationCallbacks); if(mywav->sampleRate>44100*((int)(Option.CPU_Speed/126000)))error("Max %KHz sample rate",44100*((int)(Option.CPU_Speed/126000))); // PInt(mywav.channels);MMPrintString(" Channels\r\n"); // PInt(mywav.bitsPerSample);MMPrintString(" Bits per sample\r\n"); // PInt(mywav.sampleRate);MMPrintString(" Sample rate\r\n"); if(Option.AUDIO_L){ audiorepeat=1; actualrate=mywav->sampleRate; while(actualrate<32000){ actualrate +=mywav->sampleRate; audiorepeat++; } setrate(actualrate); } else { setrate(mywav->sampleRate); } FreeMemorySafe((void **)&sbuff1); FreeMemorySafe((void **)&sbuff2); sbuff1 = GetMemory(WAV_BUFFER_SIZE); sbuff2 = GetMemory(WAV_BUFFER_SIZE); ubuff1 = (uint16_t *)sbuff1; ubuff2 = (uint16_t *)sbuff2; mono=(mywav->channels == 1 ? 1 : 0); g_buff1 = (int16_t *)sbuff1; g_buff2 = (int16_t *)sbuff2; bcount[1]=(volatile unsigned int)drwav_read_pcm_frames_s16(mywav, WAV_BUFFER_SIZE/4, (drwav_int16*)sbuff1) * mywav->channels; if(Option.audio_i2s_bclk) i2sconvert((drwav_int16*)sbuff1,(drwav_int16*)sbuff1,bcount[1]); else iconvert(ubuff1, (int16_t *)sbuff1, bcount[1]); wav_filesize=bcount[1]; CurrentlyPlaying = P_WAV; swingbuf=1; nextbuf=2; ppos=0; playreadcomplete=0; pwm_set_irq0_enabled(AUDIO_SLICE, true); pwm_set_enabled(AUDIO_SLICE, true); } void mp3callback(char *p, int position){ if(strchr((char *)p, '.') == NULL) strcat((char *)p, ".mp3"); if(CurrentlyPlaying == P_MP3){ CloseAudio(0); } WAV_fnbr = FindFreeFileNbr(); strcpy(WAVfilename,p); if(!BasicFileOpen(p, WAV_fnbr, FA_READ)) return; if(Option.AUDIO_MISO_PIN){ positionfile(WAV_fnbr, position); playvs1053(P_MP3); return; } #ifdef rp2350 int actualrate; drmp3_allocation_callbacks allocationCallbacks; allocationCallbacks.pUserData = NULL; allocationCallbacks.onMalloc = my_malloc; allocationCallbacks.onRealloc = my_realloc; allocationCallbacks.onFree = my_free; if(CurrentlyPlaying == P_MP3){ CloseAudio(0); } mymp3=GetMemory(sizeof(drmp3)); if(drmp3_init(mymp3, (drmp3_read_proc)onRead, (drmp3_seek_proc)onSeek, NULL, &allocationCallbacks)==DRMP3_FALSE)error("Mp3 init"); FreeMemorySafe((void *)&sbuff1); FreeMemorySafe((void *)&sbuff2); // PInt(mymp3->channels);MMPrintString(" Channels\r\n"); // PInt(mymp3->sampleRate);MMPrintString(" Sample rate\r\n"); sbuff1 = GetMemory(MP3_BUFFER_SIZE); sbuff2 = GetMemory(MP3_BUFFER_SIZE); ubuff1 = (uint16_t *)sbuff1; ubuff2 = (uint16_t *)sbuff2; g_buff1 = (int16_t *)sbuff1; g_buff2 = (int16_t *)sbuff2; mono=(mymp3->channels == 1 ? 1 : 0); if(Option.AUDIO_L){ audiorepeat=1; actualrate=mymp3->sampleRate; while(actualratesampleRate; audiorepeat++; } setrate(actualrate); } else { setrate(mymp3->sampleRate); } bcount[1]=drmp3_read_pcm_frames_s16(mymp3, MP3_BUFFER_SIZE/4, (drmp3_int16*)sbuff1) * mymp3->channels; if(!Option.audio_i2s_bclk)iconvert(ubuff1, (int16_t *)sbuff1, bcount[1]); else i2sconvert(g_buff1, (int16_t *)sbuff1, bcount[1]); wav_filesize=bcount[1]; CurrentlyPlaying = P_MP3; swingbuf=1; nextbuf=2; ppos=0; playreadcomplete=0; pwm_set_irq0_enabled(AUDIO_SLICE, true); pwm_set_enabled(AUDIO_SLICE, true); // MMPrintString("Playing ");MMPrintString(p);PRet(); #endif } void midicallback(char *p){ if(strchr((char *)p, '.') == NULL) strcat((char *)p, ".mid"); if(CurrentlyPlaying == P_MIDI){ CloseAudio(0); } WAV_fnbr = FindFreeFileNbr(); if(!BasicFileOpen(p, WAV_fnbr, FA_READ)) return; strcpy(WAVfilename,p); playvs1053(P_MIDI); } void flaccallback(char *p){ int actualrate; if(strchr((char *)p, '.') == NULL) strcat((char *)p, ".flac"); if(CurrentlyPlaying == P_FLAC){ CloseAudio(0); } WAV_fnbr = FindFreeFileNbr(); if(!BasicFileOpen(p, WAV_fnbr, FA_READ)) return; strcpy(WAVfilename,p); if(Option.AUDIO_MISO_PIN){ playvs1053(P_FLAC); return; } drflac_allocation_callbacks allocationCallbacks; allocationCallbacks.pUserData = NULL; allocationCallbacks.onMalloc = my_malloc; allocationCallbacks.onRealloc = my_realloc; allocationCallbacks.onFree = my_free; myflac=drflac_open((drflac_read_proc)onRead, (drflac_seek_proc)onSeek, NULL, &allocationCallbacks); #ifdef rp2350 if(myflac->sampleRate>48000*((int)((float)Option.CPU_Speed/126000.0f)))error("Max %KHz sample rate",48000*((int)((float)Option.CPU_Speed/126000.0f))); #else if(myflac->sampleRate>44100*((int)((float)Option.CPU_Speed/126000.0f)))error("Max %KHz sample rate",44100*((int)((float)Option.CPU_Speed/126000.0f))); #endif // PInt(myflac->channels);MMPrintString(" Channels\r\n"); // PInt(myflac->bitsPerSample);MMPrintString(" Bits per sample\r\n"); // PInt(myflac->sampleRate);MMPrintString(" Sample rate\r\n"); mono=(myflac->channels == 1 ? 1 : 0); if(Option.AUDIO_L){ audiorepeat=1; actualrate=myflac->sampleRate; while(actualratesampleRate; audiorepeat++; } setrate(actualrate); } else { setrate(myflac->sampleRate); } FreeMemorySafe((void **)&sbuff1); FreeMemorySafe((void **)&sbuff2); sbuff1 = GetMemory(FLAC_BUFFER_SIZE); sbuff2 = GetMemory(FLAC_BUFFER_SIZE); ubuff1 = (uint16_t *)sbuff1; ubuff2 = (uint16_t *)sbuff2; g_buff1 = (int16_t *)sbuff1; g_buff2 = (int16_t *)sbuff2; if(Option.audio_i2s_bclk){ bcount[1]=(volatile unsigned int)drflac_read_pcm_frames_s16(myflac, FLAC_BUFFER_SIZE/4, (drwav_int16*)sbuff1) * myflac->channels; i2sconvert((drwav_int16*)sbuff1,(drwav_int16*)sbuff1,bcount[1]); } else { bcount[1]=(volatile unsigned int)drflac_read_pcm_frames_s16(myflac, FLAC_BUFFER_SIZE/4, (drwav_int16*)sbuff1) * myflac->channels; iconvert(ubuff1, (int16_t *)sbuff1, bcount[1]); } wav_filesize=bcount[1]; CurrentlyPlaying = P_FLAC; swingbuf=1; nextbuf=2; ppos=0; playreadcomplete=0; pwm_set_irq0_enabled(AUDIO_SLICE, true); pwm_set_enabled(AUDIO_SLICE, true); } void rampvolume(int l, int r, int channel, int target){ if(optionfastaudio){ if(l)sound_v_left[channel]=target; if(r)sound_v_right[channel]=target; } else { int ramptime=1000000/PWM_FREQ+2; if(l && r){ if(sound_v_left[channel]>target){ for(int i=sound_v_left[channel]-1;i>=target;i--){ sound_v_left[channel]=i; sound_v_right[channel]=i; uSec(ramptime); } } else { for(int i=sound_v_left[channel]+1;i<=target;i++){ sound_v_left[channel]=i; sound_v_right[channel]=i; uSec(ramptime); } } } else if(l){ if(sound_v_left[channel]>target){ for(int i=sound_v_left[channel]-1;i>=target;i--){ sound_v_left[channel]=i; uSec(ramptime); } } else { for(int i=sound_v_left[channel]+1;i<=target;i++){ sound_v_left[channel]=i; uSec(ramptime); } } } else if(r){ if(sound_v_right[channel]>target){ for(int i=sound_v_right[channel]-1;i>=target;i--){ sound_v_right[channel]=i; uSec(ramptime); } } else { for(int i=sound_v_right[channel]+1;i<=target;i++){ sound_v_right[channel]=i; uSec(ramptime); } } } } } void setnoise(void){ uint32_t noise; int i; if(noisetable)return; noisetable=GetMemory(4096*sizeof(uint16_t)); for(i=0;i<4096;i++){ noise=rand() % 3800+100; noisetable[i]=(int)noise; } return; } /* @endcond */ // The MMBasic command: PLAY void MIPS16 cmd_play(void) { unsigned char *tp; if(checkstring(cmdline, (unsigned char *)"STOP")) { if(CurrentlyPlaying == P_NOTHING)return; CloseAudio(1); return; } if(!(Option.AUDIO_L || Option.AUDIO_CLK_PIN || Option.audio_i2s_bclk))error((char *)"Audio not enabled"); if((tp=checkstring(cmdline, (unsigned char *)"LOAD SOUND"))) { if(Option.AUDIO_MISO_PIN)error("Not available with VS1053 audio"); if(usertable!=NULL)error("Already loaded"); // unsigned int nbr; uint16_t *dd; int64_t *aint; skipspace(tp); int size=parseintegerarray(tp,&aint,1,1,NULL,false); dd = (uint16_t *)aint; if(size!=1024) error("Array size"); usertable=dd; return; } if(checkstring(cmdline, (unsigned char *)"NEXT")) { if(CurrentlyPlaying == P_FLAC){ if(trackplaying==trackstoplay){ if(!CurrentLinePtr)MMPrintString("Last track is playing\r\n"); return; } trackplaying++; flaccallback(alist[trackplaying].fn); } else if(CurrentlyPlaying == P_WAV){ if(trackplaying==trackstoplay){ if(!CurrentLinePtr)MMPrintString("Last track is playing\r\n"); return; } trackplaying++; wavcallback(alist[trackplaying].fn); } else if(CurrentlyPlaying == P_MP3){ if(trackplaying==trackstoplay){ if(!CurrentLinePtr)MMPrintString("Last track is playing\r\n"); return; } trackplaying++; mp3callback(alist[trackplaying].fn,0); } else if(CurrentlyPlaying == P_MIDI){ if(trackplaying==trackstoplay){ if(!CurrentLinePtr)MMPrintString("Last track is playing\r\n"); return; } trackplaying++; midicallback(alist[trackplaying].fn); } else error("Nothing to play"); return; } if(checkstring(cmdline, (unsigned char *)"PREVIOUS")) { if(CurrentlyPlaying == P_FLAC){ if(trackplaying==0){ if(!CurrentLinePtr)MMPrintString("First track is playing\r\n"); return; } trackplaying--; flaccallback(alist[trackplaying].fn); } else if(CurrentlyPlaying == P_WAV){ if(trackplaying==0){ if(!CurrentLinePtr)MMPrintString("First track is playing\r\n"); return; } trackplaying--; wavcallback(alist[trackplaying].fn); } else if(CurrentlyPlaying == P_MP3){ if(trackplaying==0){ if(!CurrentLinePtr)MMPrintString("First track is playing\r\n"); return; } trackplaying--; mp3callback(alist[trackplaying].fn,0); } else if(CurrentlyPlaying == P_MIDI){ if(trackplaying==0){ if(!CurrentLinePtr)MMPrintString("First track is playing\r\n"); return; } trackplaying--; midicallback(alist[trackplaying].fn); } else error("Nothing to play"); return; } if(checkstring(cmdline, (unsigned char *)"PAUSE")) { if(CurrentlyPlaying22050.0)error("Valid is 0Hz to 20KHz"); if(f_right<0.0 || f_right>22050.0)error("Valid is 0Hz to 20KHz"); if(argc > 4) { duration = ((float)getint(argv[4], 0, INT_MAX)/1000.0); //tone duration in seconds PlayDuration=(uint64_t)duration; } else duration=1; if(argc == 7) { if(!CurrentLinePtr)error("No program running"); WAVInterrupt = (char *)GetIntAddress(argv[6]); // get the interrupt location WAVcomplete=false; InterruptUsed = true; } if(duration == 0) return; if(PlayDuration != 0xffffffffffffffff && f_left >=10.0){ hw=((float)PWM_FREQ/(float)f_left); //number of interrupts per cycle duration = duration * (float)PWM_FREQ; // number of interrupts for the requested waveform // This should now be an exact multiple of the number per waveform PlayDuration=(((uint64_t)(duration/hw))*hw); } pwm_set_irq0_enabled(AUDIO_SLICE, false); PhaseM_left = f_left / (float)PWM_FREQ * 4096.0; PhaseM_right = f_right / (float)PWM_FREQ * 4096.0; WAV_fnbr=0; SoundPlay = PlayDuration; if (!(CurrentlyPlaying == P_PAUSE_TONE || CurrentlyPlaying == P_TONE )){ setrate(PWM_FREQ); PhaseAC_right=0.0; PhaseAC_left=0.0; if(Option.AUDIO_MISO_PIN)playimmediatevs1053(P_TONE); } CurrentlyPlaying = P_TONE; pwm_set_irq0_enabled(AUDIO_SLICE, true); pwm_set_enabled(AUDIO_SLICE, true); return; } } if((tp = checkstring(cmdline, (unsigned char *)"SOUND"))) {//PLAY SOUND channel, type, position, frequency, volume float f_in, PhaseM; int channel, left=0, right=0, lset=0, rset=0, local_sound_v_left=0,local_sound_v_right=0; char *p; uint16_t *lastleft=NULL, *lastright=NULL, *local_sound_mode_left=(uint16_t *)nulltable, *local_sound_mode_right=(uint16_t *)nulltable; // get the command line arguments getargs(&tp, 9,(unsigned char *)","); // this MUST be the first executable line in the function if(!(argc == 9 || argc == 7 || argc == 5)) error("Argument count"); if(checkstring(argv[4],(unsigned char *)"O")==NULL && argc == 5) error("Argument count"); WAV_fnbr=0; channel=getint(argv[0],1,MAXSOUNDS)-1; lastleft=local_sound_mode_left=(uint16_t *)sound_mode_left[channel]; lastright=local_sound_mode_right=(uint16_t *)sound_mode_right[channel]; if(checkstring(argv[2],(unsigned char *)"L")!=NULL){ left=1; } else if(checkstring(argv[2],(unsigned char *)"R")!=NULL){ right=1; } else if(checkstring(argv[2],(unsigned char *)"B")!=NULL){ right=1; left=1; } else { p=(char *)getCstring(argv[2]); if(strcasecmp(p,"B")==0){ right=1; left=1; } else if(strcasecmp(p,"M")==0){ right=1; left=1; } else if (strcasecmp(p,"L")==0){ left=1; } else if (strcasecmp(p,"R")==0){ right=1; } else error("Position must be L, R, or B"); } if(!(CurrentlyPlaying == P_NOTHING || CurrentlyPlaying == P_SOUND || CurrentlyPlaying == P_PAUSE_SOUND || CurrentlyPlaying == P_STOP || CurrentlyPlaying == P_WAVOPEN)) error("Sound output in use for $",PlayingStr[CurrentlyPlaying]); if(checkstring(argv[4],(unsigned char *)"O")!=NULL && left){lset=1;local_sound_mode_left=(uint16_t *)nulltable;} if(checkstring(argv[4],(unsigned char *)"O")!=NULL && right){rset=1;local_sound_mode_right=(uint16_t *)nulltable;} if(checkstring(argv[4],(unsigned char *)"Q")!=NULL && left){lset=1;local_sound_mode_left=(uint16_t *)squaretable;} if(checkstring(argv[4],(unsigned char *)"Q")!=NULL && right){rset=1;local_sound_mode_right=(uint16_t *)squaretable;} if(checkstring(argv[4],(unsigned char *)"T")!=NULL && left){lset=1;local_sound_mode_left=(uint16_t *)triangletable;} if(checkstring(argv[4],(unsigned char *)"T")!=NULL && right){rset=1;local_sound_mode_right=(uint16_t *)triangletable;} if(checkstring(argv[4],(unsigned char *)"W")!=NULL && left){lset=1;local_sound_mode_left=(uint16_t *)sawtable;} if(checkstring(argv[4],(unsigned char *)"W")!=NULL && right){rset=1;local_sound_mode_right=(uint16_t *)sawtable;} if(checkstring(argv[4],(unsigned char *)"S")!=NULL && left){lset=1;local_sound_mode_left=(uint16_t *)SineTable;} if(checkstring(argv[4],(unsigned char *)"S")!=NULL && right){rset=1;local_sound_mode_right=(uint16_t *)SineTable;} if(checkstring(argv[4],(unsigned char *)"P")!=NULL && left){lset=1;setnoise();local_sound_mode_left=(uint16_t *)noisetable;} if(checkstring(argv[4],(unsigned char *)"P")!=NULL && right){rset=1;setnoise();local_sound_mode_right=(uint16_t *)noisetable;} if(checkstring(argv[4],(unsigned char *)"N")!=NULL && left){lset=1;local_sound_mode_left=(uint16_t *)whitenoise;} if(checkstring(argv[4],(unsigned char *)"N")!=NULL && right){rset=1;local_sound_mode_right=(uint16_t *)whitenoise;} if(checkstring(argv[4],(unsigned char *)"U")!=NULL && left){lset=1;local_sound_mode_left=(uint16_t *)usertable;} if(checkstring(argv[4],(unsigned char *)"U")!=NULL && right){rset=1;local_sound_mode_right=(uint16_t *)usertable;} if(left && lset==0){ p=(char *)getCstring(argv[4]); if(strcasecmp(p,"O")==0)local_sound_mode_left=(uint16_t *)nulltable; if(strcasecmp(p,"Q")==0)local_sound_mode_left=(uint16_t *)squaretable; if(strcasecmp(p,"T")==0)local_sound_mode_left=(uint16_t *)triangletable; if(strcasecmp(p,"W")==0)local_sound_mode_left=(uint16_t *)sawtable; if(strcasecmp(p,"S")==0)local_sound_mode_left=(uint16_t *)SineTable; if(strcasecmp(p,"P")==0){setnoise();local_sound_mode_left=(uint16_t *)noisetable;} if(strcasecmp(p,"N")==0)local_sound_mode_left=(uint16_t *)whitenoise; if(strcasecmp(p,"U")==0)local_sound_mode_left=(uint16_t *)usertable; if(local_sound_mode_left==NULL)error("Invalid type"); else lset=1; } if(right && rset==0){ p=(char *)getCstring(argv[4]); if(strcasecmp(p,"O")==0)local_sound_mode_right=(uint16_t *)nulltable; if(strcasecmp(p,"Q")==0)local_sound_mode_right=(uint16_t *)squaretable; if(strcasecmp(p,"T")==0)local_sound_mode_right=(uint16_t *)triangletable; if(strcasecmp(p,"W")==0)local_sound_mode_right=(uint16_t *)sawtable; if(strcasecmp(p,"S")==0)local_sound_mode_right=(uint16_t *)SineTable; if(strcasecmp(p,"P")==0){setnoise();local_sound_mode_right=(uint16_t *)noisetable;;} if(strcasecmp(p,"N")==0)local_sound_mode_right=(uint16_t *)whitenoise; if(strcasecmp(p,"U")==0)local_sound_mode_right=(uint16_t *)usertable; if(local_sound_mode_right==NULL)error("Invalid type"); else rset=1; } if((local_sound_mode_left==usertable || local_sound_mode_right==usertable) && usertable==NULL) error("Not loaded"); f_in=10.0; if(argc>=7)f_in = getnumber(argv[6]); // get the arguments if(f_in<1.0 || f_in>20000.0)error("Valid is 1Hz to 20KHz"); if(left){ if(!(sound_mode_left[channel]==whitenoise )){ PhaseM = f_in / (float)PWM_FREQ * 4096.0; } else { PhaseM = f_in; } if(lastleft!=local_sound_mode_left){ if(!Option.AUDIO_MISO_PIN)rampvolume(1,0,channel,0); sound_PhaseAC_left[channel] = 0.0; } sound_PhaseM_left[channel] = PhaseM; if(argc==9)local_sound_v_left=getint(argv[8],0,100/MAXSOUNDS); else local_sound_v_left=25; local_sound_v_left=local_sound_v_left*41/(100/MAXSOUNDS); } if(right){ if(!(sound_mode_right[channel]==whitenoise )){ PhaseM = f_in / (float)PWM_FREQ * 4096.0; } else { PhaseM = f_in; } if(lastright!=local_sound_mode_right){ if(!Option.AUDIO_MISO_PIN)rampvolume(0,1,channel,0); sound_PhaseAC_right[channel] = 0.0; } sound_PhaseM_right[channel] = PhaseM; if(argc==9)local_sound_v_right=getint(argv[8],0,100/MAXSOUNDS); else local_sound_v_right=25; local_sound_v_right=local_sound_v_right*41/(100/MAXSOUNDS); } if(left && right && local_sound_v_left==local_sound_v_right && sound_v_left[channel]==sound_v_right[channel] && !Option.AUDIO_MISO_PIN)rampvolume(1,1,channel,local_sound_v_left); else { if(left && !Option.AUDIO_MISO_PIN)rampvolume(1,0,channel,local_sound_v_left); if(right && !Option.AUDIO_MISO_PIN)rampvolume(0,1,channel,local_sound_v_right); } if(left)sound_mode_left[channel]=local_sound_mode_left; if(right)sound_mode_right[channel]=local_sound_mode_right; if(!(CurrentlyPlaying == P_SOUND || CurrentlyPlaying==P_PAUSE_SOUND)){ setrate(PWM_FREQ); if(Option.AUDIO_MISO_PIN)playimmediatevs1053(P_SOUND); pwm_set_irq0_enabled(AUDIO_SLICE, true); pwm_set_enabled(AUDIO_SLICE, true); } CurrentlyPlaying = P_SOUND; return; } if((tp = checkstring(cmdline, (unsigned char *)"WAV"))) { char *p; int i __attribute((unused))=0; getargs(&tp, 3,(unsigned char *)","); // this MUST be the first executable line in the function if(!(argc == 1 || argc == 3)) error("Argument count"); if(CurrentlyPlaying==P_WAVOPEN)CloseAudio(1); if(CurrentlyPlaying != P_NOTHING) error("Sound output in use for $",PlayingStr[CurrentlyPlaying]); if(!InitSDCard()) return; p = (char *)getFstring(argv[0]); // get the file name char q[FF_MAX_LFN]={0}; getfullfilename(p,q); WAVInterrupt = NULL; WAVcomplete = 0; if(argc == 3) { if(!CurrentLinePtr)error("No program running"); WAVInterrupt = (char *)GetIntAddress(argv[2]); // get the interrupt location InterruptUsed = true; } if(FatFSFileSystem){ FRESULT fr; FILINFO fno; int i; if(ExistsDir(q,q,&i)){ alist=GetMemory(sizeof(a_flist)*MAXALBUM); trackstoplay=0; trackplaying=0; DIR djd; djd.pat="*.wav"; if(!CurrentLinePtr)MMPrintString("Directory found - commencing player\r\n"); FSerror = f_opendir(&djd, q); for(;;){ fr=f_readdir(&djd, &fno); if (fr != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ // Get a directory item if (pattern_matching(djd.pat, fno.fname, 0, 0)){ // Get a directory item strcpy(alist[trackstoplay].fn,"B:"); strcat(alist[trackstoplay].fn,q); strcat(alist[trackstoplay].fn,"/"); strcat(alist[trackstoplay].fn,fno.fname); str_replace(alist[trackstoplay].fn, "//", "/",3); str_replace(alist[trackstoplay].fn, "/./", "/",3); if(!CurrentLinePtr){ MMPrintString(fno.fname); PRet(); } trackstoplay++; if(trackstoplay==MAXALBUM)break; } } trackstoplay--; f_closedir(&djd); wavcallback(alist[trackplaying].fn); return; } } // open the file trackstoplay=0; trackplaying=0; memset(q,0,sizeof(q)); getfullfilename(p,q); memmove(&q[2],q,strlen(q)); q[1]=':'; q[0]=FatFSFileSystem ? 'B' : 'A'; wavcallback(q); return; } if((tp = checkstring(cmdline, (unsigned char *)"FLAC"))) { char *p; int i __attribute((unused))=0; getargs(&tp, 3,(unsigned char *)","); // this MUST be the first executable line in the function if(!(argc == 1 || argc == 3)) error("Argument count"); if(CurrentlyPlaying==P_WAVOPEN)CloseAudio(1); if(CurrentlyPlaying != P_NOTHING) error("Sound output in use for $",PlayingStr[CurrentlyPlaying]); if(!InitSDCard()) return; p = (char *)getFstring(argv[0]); // get the file name char q[FF_MAX_LFN]={0}; getfullfilename(p,q); WAVInterrupt = NULL; WAVcomplete = 0; if(argc == 3) { if(!CurrentLinePtr)error("No program running"); WAVInterrupt = (char *)GetIntAddress(argv[2]); // get the interrupt location InterruptUsed = true; } if(FatFSFileSystem){ FRESULT fr; FILINFO fno; int i; if(ExistsDir(q,q,&i)){ alist=GetMemory(sizeof(a_flist)*MAXALBUM); trackstoplay=0; trackplaying=0; DIR djd; djd.pat="*.flac"; if(!CurrentLinePtr)MMPrintString("Directory found - commencing player\r\n"); FSerror = f_opendir(&djd, q); for(;;){ fr=f_readdir(&djd, &fno); if (fr != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ // Get a directory item if (pattern_matching(djd.pat, fno.fname, 0, 0)){ // Get a directory item strcpy(alist[trackstoplay].fn,"B:"); strcat(alist[trackstoplay].fn,q); strcat(alist[trackstoplay].fn,"/"); strcat(alist[trackstoplay].fn,fno.fname); str_replace(alist[trackstoplay].fn, "//", "/",3); str_replace(alist[trackstoplay].fn, "/./", "/",3); if(!CurrentLinePtr){ MMPrintString(fno.fname); PRet(); } trackstoplay++; if(trackstoplay==MAXALBUM)break; } } trackstoplay--; f_closedir(&djd); flaccallback(alist[trackplaying].fn); return; } } // open the file trackstoplay=0; trackplaying=0; memset(q,0,sizeof(q)); getfullfilename(p,q); memmove(&q[2],q,strlen(q)); q[1]=':'; q[0]=FatFSFileSystem ? 'B' : 'A'; flaccallback(q); return; } if((tp = checkstring(cmdline, (unsigned char *)"NOTE"))) { if(!Option.AUDIO_MISO_PIN)error("Only available with VS1053 audio"); if(!midienabled)error("Midi output not enabled"); unsigned char *xp; if((xp = checkstring(tp, (unsigned char *)"ON"))) { getargs(&xp,5,(unsigned char *)","); if(!(argc==5))error("Syntax"); uint8_t channel=getint(argv[0],0,15); uint8_t note=getint(argv[2],0,127); uint8_t velocity=getint(argv[4],0,127); noteOn(channel,note,velocity); } else if((xp = checkstring(tp, (unsigned char *)"OFF"))) { getargs(&xp,5,(unsigned char *)","); if(!(argc==5 || argc==3))error("Syntax"); uint8_t channel=getint(argv[0],0,15); uint8_t note=getint(argv[2],0,127); uint8_t velocity=0; if(argc==5)velocity=getint(argv[4],0,127); noteOff(channel,note,velocity); } else error("Syntax"); return; } if((tp = checkstring(cmdline, (unsigned char *)"STREAM"))) { getargs(&tp,5,(unsigned char *)","); if(!(argc == 5 )) error("Syntax"); if(!Option.AUDIO_MISO_PIN)error("Only available with VS1053 audio"); if(CurrentlyPlaying==P_WAVOPEN)CloseAudio(1); if(CurrentlyPlaying != P_NOTHING) error("Sound output in use for $",PlayingStr[CurrentlyPlaying]); WAVInterrupt = NULL; WAVcomplete = 0; if(XDCS!=-1)error("VS1053 already open"); void *ptr1 = NULL; int64_t *aint; streamsize=parseintegerarray(argv[0], &aint, 1, 1, NULL, true) * 8; streambuffer=(char *)aint; ptr1 = findvar(argv[2], V_FIND | V_EMPTY_OK | V_NOFIND_ERR); if(g_vartbl[g_VarIndex].type & T_INT) { if(g_vartbl[g_VarIndex].dims[0] != 0) error("Argument 2 must be an integer"); streamreadpointer = (int *)ptr1; } else error("Argument 2 must be an integer"); ptr1 = findvar(argv[4], V_FIND | V_EMPTY_OK | V_NOFIND_ERR); if(g_vartbl[g_VarIndex].type & T_INT) { if(g_vartbl[g_VarIndex].dims[0] != 0) error("Argument 3 must be an integer"); streamwritepointer = (int *)ptr1; } else error("Argument 3 must be an integer"); XCS=PinDef[Option.AUDIO_CS_PIN].GPno; XDCS=PinDef[Option.AUDIO_DCS_PIN].GPno; DREQ=PinDef[Option.AUDIO_DREQ_PIN].GPno; XRST=PinDef[Option.AUDIO_RESET_PIN].GPno; VS1053(XCS,XDCS,DREQ,XRST); switchToMp3Mode(); loadDefaultVs1053Patches(); setVolumes(vol_left,vol_right); MMPrintString("Stream output enabled\r\n"); playreadcomplete=0; CurrentlyPlaying=P_STREAM; setrate(16000); //16KHz should be fast enough pwm_set_irq0_enabled(AUDIO_SLICE, true); pwm_set_enabled(AUDIO_SLICE, true); return; } if((tp = checkstring(cmdline, (unsigned char *)"MIDI"))) { unsigned char *xp; if((xp = checkstring(tp, (unsigned char *)"CMD"))) { getargs(&xp,5,(unsigned char *)","); if(!midienabled)error("Midi output not enabled"); if(!(argc==5 || argc==3))error("Syntax"); uint8_t cmd=getint(argv[0],128,255); uint8_t data1=getint(argv[2],0,127); uint8_t data2=0; if(argc==5)data2=getint(argv[4],0,127); talkMIDI(cmd, data1, data2); return; } if((xp = checkstring(tp, (unsigned char *)"TEST"))) { getargs(&xp,1,(unsigned char *)","); if(!midienabled)error("Midi output not enabled"); miditest(getint(argv[0],1,3)); return; } if(!Option.AUDIO_MISO_PIN)error("Only available with VS1053 audio"); if(CurrentlyPlaying==P_WAVOPEN)CloseAudio(1); if(CurrentlyPlaying != P_NOTHING) error("Sound output in use for $",PlayingStr[CurrentlyPlaying]); WAVInterrupt = NULL; WAVcomplete = 0; XCS=PinDef[Option.AUDIO_CS_PIN].GPno; XDCS=PinDef[Option.AUDIO_DCS_PIN].GPno; DREQ=PinDef[Option.AUDIO_DREQ_PIN].GPno; XRST=PinDef[Option.AUDIO_RESET_PIN].GPno; VS1053(XCS,XDCS,DREQ,XRST); setVolumes(vol_left,vol_right); midienabled=1; miditest(0); if(!CurrentLinePtr)MMPrintString("Real Time MIDI mode enabled\r\n"); return; } if((tp = checkstring(cmdline, (unsigned char *)"MIDIFILE"))) { char *p; int i __attribute((unused))=0; getargs(&tp, 3,(unsigned char *)","); // this MUST be the first executable line in the function if(!(argc == 1 || argc == 3)) error("Argument count"); if(!Option.AUDIO_MISO_PIN)error("Only available with VS1053 audio"); if(CurrentlyPlaying==P_WAVOPEN)CloseAudio(1); if(CurrentlyPlaying != P_NOTHING) error("Sound output in use for $",PlayingStr[CurrentlyPlaying]); if(!InitSDCard()) return; p = (char *)getFstring(argv[0]); // get the file name char q[FF_MAX_LFN]={0}; getfullfilename(p,q); WAVInterrupt = NULL; WAVcomplete = 0; if(argc == 3) { if(!CurrentLinePtr)error("No program running"); WAVInterrupt = (char *)GetIntAddress(argv[2]); // get the interrupt location InterruptUsed = true; } if(FatFSFileSystem){ FRESULT fr; FILINFO fno; int i; if(ExistsDir(q,q,&i)){ alist=GetMemory(sizeof(a_flist)*MAXALBUM); trackstoplay=0; trackplaying=0; DIR djd; djd.pat="*.mid"; if(!CurrentLinePtr)MMPrintString("Directory found - commencing player\r\n"); FSerror = f_opendir(&djd, q); for(;;){ fr=f_readdir(&djd, &fno); if (fr != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ // Get a directory item if (pattern_matching(djd.pat, fno.fname, 0, 0)){ // Get a directory item strcpy(alist[trackstoplay].fn,"B:"); strcat(alist[trackstoplay].fn,q); strcat(alist[trackstoplay].fn,"/"); strcat(alist[trackstoplay].fn,fno.fname); str_replace(alist[trackstoplay].fn, "//", "/",3); str_replace(alist[trackstoplay].fn, "/./", "/",3); if(!CurrentLinePtr){ MMPrintString(fno.fname); PRet(); } trackstoplay++; if(trackstoplay==MAXALBUM)break; } } trackstoplay--; f_closedir(&djd); midicallback(alist[trackplaying].fn); return; } } // open the file trackstoplay=0; trackplaying=0; memset(q,0,sizeof(q)); getfullfilename(p,q); memmove(&q[2],q,strlen(q)); q[1]=':'; q[0]=FatFSFileSystem ? 'B' : 'A'; midicallback(q); return; } if((tp = checkstring(cmdline, (unsigned char *)"HALT"))) { if(CurrentlyPlaying != P_MP3) error("Not playing an MP3"); int fnbr = FindFreeFileNbr(); char *buff=GetTempMemory(STRINGSIZE); char *p=&WAVfilename[strlen(WAVfilename)]; while(*p-- != '/'){} p+=2; strcpy(buff,"A:/"); strcat(buff,p); str_replace(buff,".mp3",".mem",1); str_replace(buff,".MP3",".mem",1); str_replace(buff,".Mp3",".mem",1); str_replace(buff,".mP3",".mem",1); if(!BasicFileOpen(buff, fnbr, FA_WRITE | FA_CREATE_ALWAYS)) return; int i; if(filesource[WAV_fnbr]==FLASHFILE)i = lfs_file_tell(&lfs,FileTable[fnbr].lfsptr) + 1; else i = (*(FileTable[WAV_fnbr].fptr)).fptr + 1; i-=418; if(i<0)i=0; IntToStr(buff,i,10); FilePutStr(strlen(buff),buff,fnbr); FilePutChar(',',fnbr); FilePutStr(strlen(WAVfilename),WAVfilename,fnbr); FileClose(fnbr); CloseAudio(1); return; } if((tp = checkstring(cmdline, (unsigned char *)"CONTINUE"))) { if(!Option.AUDIO_MISO_PIN)error("Only available with VS1053 audio"); int fnbr = FindFreeFileNbr(); char *p=(char *)getFstring(tp); char *buff=GetTempMemory(STRINGSIZE); if(strchr(p,'/') || strchr(p,':') || strchr(p,'\\') || strchr(p,'.'))error("Track name"); strcpy(buff, "A:/"); strcat(buff,p); strcat(buff,".mem"); if(!ExistsFile(buff))error("Track name"); if(!BasicFileOpen(buff, fnbr, FA_READ)) return; memset(buff,0,STRINGSIZE); lfs_file_read(&lfs, FileTable[fnbr].lfsptr, buff, 255); FileClose(fnbr); p=strchr(buff,','); p++; int num=atoi(buff); WAVInterrupt = NULL; WAVcomplete = 0; trackstoplay=0; trackplaying=0; mp3callback(p,num); return; } if((tp = checkstring(cmdline, (unsigned char *)"MP3"))) { char *p; int i __attribute((unused))=0; getargs(&tp, 3,(unsigned char *)","); // this MUST be the first executable line in the function if(!(argc == 1 || argc == 3)) error("Argument count"); #ifndef rp2350 if(!Option.AUDIO_MISO_PIN)error("Only available with VS1053 audio"); #else if(Option.CPU_Speed<200000 && !Option.AUDIO_MISO_PIN)error("CPUSPEED >=200000 for MP3 playback"); #endif if(CurrentlyPlaying==P_WAVOPEN)CloseAudio(1); if(CurrentlyPlaying != P_NOTHING) error("Sound output in use for $",PlayingStr[CurrentlyPlaying]); if(!InitSDCard()) return; p = (char *)getFstring(argv[0]); // get the file name char q[FF_MAX_LFN]={0}; getfullfilename(p,q); WAVInterrupt = NULL; WAVcomplete = 0; if(argc == 3) { if(!CurrentLinePtr)error("No program running"); WAVInterrupt = (char *)GetIntAddress(argv[2]); // get the interrupt location InterruptUsed = true; } if(FatFSFileSystem){ FRESULT fr; FILINFO fno; int i; if(ExistsDir(q,q,&i)){ alist=GetMemory(sizeof(a_flist)*MAXALBUM); trackstoplay=0; trackplaying=0; DIR djd; djd.pat="*.mp3"; if(!CurrentLinePtr)MMPrintString("Directory found - commencing player\r\n"); FSerror = f_opendir(&djd, q); for(;;){ fr=f_readdir(&djd, &fno); if (fr != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ // Get a directory item if (pattern_matching(djd.pat, fno.fname, 0, 0)){ // Get a directory item strcpy(alist[trackstoplay].fn,"B:"); strcat(alist[trackstoplay].fn,q); strcat(alist[trackstoplay].fn,"/"); strcat(alist[trackstoplay].fn,fno.fname); str_replace(alist[trackstoplay].fn, "//", "/",3); str_replace(alist[trackstoplay].fn, "/./", "/",3); if(!CurrentLinePtr){ MMPrintString(fno.fname); PRet(); } trackstoplay++; if(trackstoplay==MAXALBUM)break; } } trackstoplay--; f_closedir(&djd); mp3callback(alist[trackplaying].fn,0); return; } } // open the file trackstoplay=0; trackplaying=0; memset(q,0,sizeof(q)); getfullfilename(p,q); memmove(&q[2],q,strlen(q)); q[1]=':'; q[0]=FatFSFileSystem ? 'B' : 'A'; mp3callback(q,0); return; } if((tp = checkstring(cmdline, (unsigned char *)"MODFILE"))) { getargs(&tp, 3,(unsigned char *)","); // this MUST be the first executable line in the function char *p; int i __attribute((unused))=0,fsize; modfilesamplerate=22050; if(CurrentlyPlaying==P_WAVOPEN)CloseAudio(1); if(CurrentlyPlaying != P_NOTHING) error("Sound output in use"); #ifdef rp2350 if(!(modbuff || PSRAMsize))error("Mod playback not enabled"); #else if(!(modbuff))error("Mod playback not enabled"); #endif if(!InitSDCard()) return; sbuff1 = GetMemory(MOD_BUFFER_SIZE); sbuff2 = GetMemory(MOD_BUFFER_SIZE); ubuff1 = (uint16_t *)sbuff1; ubuff2 = (uint16_t *)sbuff2; g_buff1 = (int16_t *)sbuff1; g_buff2 = (int16_t *)sbuff2; p = (char *)getFstring(argv[0]); // get the file name WAVInterrupt = NULL; WAVcomplete = 0; // open the file if(strchr((char *)p, '.') == NULL) strcat((char *)p, ".MOD"); char q[FF_MAX_LFN]={0}; getfullfilename(p,q); memmove(&q[2],q,strlen(q)); q[1]=':'; q[0]=FatFSFileSystem ? 'B' : 'A'; strcpy(WAVfilename,q); WAV_fnbr = FindFreeFileNbr(); if(!BasicFileOpen(p, WAV_fnbr, FA_READ)) return; if(argc==3){ if(!CurrentLinePtr)error("No program running"); WAVInterrupt = (char *)GetIntAddress(argv[2]); // get the interrupt location InterruptUsed = true; noloop=1; } else noloop=0; i=0; if(filesource[WAV_fnbr]!=FLASHFILE) fsize = f_size(FileTable[WAV_fnbr].fptr); else fsize = lfs_file_size(&lfs,FileTable[WAV_fnbr].lfsptr); int alreadythere=1; #ifdef rp2350 if(!PSRAMsize){ #endif if(RoundUpK4(fsize)>1024*Option.modbuffsize)error("File too large for modbuffer"); char *check=modbuff; while(!FileEOF(WAV_fnbr)) { if(*check++ != FileGetChar(WAV_fnbr)){ alreadythere=0; break; } } #ifdef rp2350 } else { modbuff=GetMemory(RoundUpK4(fsize)); positionfile(WAV_fnbr,0); char *r=modbuff; while(!FileEOF(WAV_fnbr)) { *r++=FileGetChar(WAV_fnbr); } } #endif if(!alreadythere){ unsigned char *r = GetTempMemory(256); positionfile(WAV_fnbr,0); uint32_t j = RoundUpK4(TOP_OF_SYSTEM_FLASH); disable_interrupts_pico(); flash_range_erase(j, RoundUpK4(fsize)); enable_interrupts_pico(); while(!FileEOF(WAV_fnbr)) { memset(r,0,256) ; for(i=0;i<256;i++) { if(FileEOF(WAV_fnbr))break; r[i] = FileGetChar(WAV_fnbr); } disable_interrupts_pico(); flash_range_program(j, (uint8_t *)r, 256); enable_interrupts_pico(); routinechecks(); j+=256; } FileClose(WAV_fnbr); } FileClose(WAV_fnbr); mcontext=GetMemory(sizeof(modcontext)); hxcmod_init( mcontext ); hxcmod_setcfg(mcontext, modfilesamplerate,1,1 ); hxcmod_load( mcontext, (void*)modbuff, fsize ); if(!mcontext->mod_loaded)error("Load failed"); if(!CurrentLinePtr){ MMPrintString("Playing ");MMPrintString((char *)mcontext->song.title);PRet(); } if(Option.AUDIO_MISO_PIN){ playvs1053(P_MOD); return; } else { hxcmod_fillbuffer( mcontext, (msample*)sbuff1, MOD_BUFFER_SIZE/8, NULL, noloop ); } wav_filesize=MOD_BUFFER_SIZE/4; bcount[1]=MOD_BUFFER_SIZE/4; bcount[2]=0; if(Option.audio_i2s_bclk)i2sconvert(g_buff1, (int16_t *)sbuff1, bcount[1]); else iconvert((uint16_t *)ubuff1, (int16_t *)sbuff1, bcount[1]); nchannels=2; CurrentlyPlaying = P_MOD; swingbuf=1; nextbuf=2; ppos=0; playreadcomplete=0; setrate(44100); audiorepeat=2; pwm_set_irq0_enabled(AUDIO_SLICE, true); pwm_set_enabled(AUDIO_SLICE, true); Timer1=500; while(Timer1){ checkWAVinput(); #ifdef PICOMITEWEB ProcessWeb(1); #endif } return; } if((tp = checkstring(cmdline, (unsigned char *)"MODSAMPLE"))) { unsigned short sampnum, seffectnum; unsigned char volume; unsigned int samprate, period; getargs(&tp, 5,(unsigned char *)","); // this MUST be the first executable line in the function if(!(argc == 5 || argc == 3)) error("Argument count"); if(!(CurrentlyPlaying == P_MOD)) error("Samples play over MOD file"); sampnum = getint(argv[0],1,32) - 1; seffectnum = getint(argv[2],1,NUMMAXSEFFECTS) - 1; volume=63; if(argc >= 5 && *argv[4]) { volume = getint(argv[4],0,64) - 1; if (volume <0 ) volume = 0; } samprate = 16000; period = 3579545 / samprate; hxcmod_playsoundeffect( mcontext, sampnum, seffectnum, volume, period ); return; } error("Unknown command"); } /* * @cond * The following section will be excluded from the documentation. */ /****************************************************************************************** Timer interrupt. Used to send data to the DAC *******************************************************************************************/ /****************************************************************************************** Stop playing the music or toneb: *******************************************************************************************/ void StopAudio(void) { if(CurrentlyPlaying != P_NOTHING ) { int ramptime=1000000/PWM_FREQ-1; pwm_set_irq0_enabled(AUDIO_SLICE, false); uSec(100); // if(!(Option.audio_i2s_bclk)) { uint32_t rr,r=right; uint32_t ll,l=left; uint32_t m=2000; l=m-l; r=m-r; for(int i=100;i>=0;i--){ ll=(uint32_t)((int)m-(int)l*i/100); rr=(uint32_t)((int)m-(int)r*i/100); AudioOutput(ll,rr); uSec(ramptime); } CurrentlyPlaying = P_STOP; uSec(ramptime*2); setrate(PWM_FREQ); } ppos=0; if(Option.AUDIO_MISO_PIN && (CurrentlyPlaying == P_TONE || CurrentlyPlaying==P_SOUND))CurrentlyPlaying = P_WAVOPEN; else CurrentlyPlaying = P_NOTHING; } SoundPlay = 0; } /****************************************************************************************** * Maintain the WAV sample buffer *******************************************************************************************/ void checkWAVinput(void){ audio_checks(); if(playreadcomplete==1)return; if(swingbuf != nextbuf){ //IR has moved to next buffer if(Option.AUDIO_MISO_PIN){ if(CurrentlyPlaying == P_FLAC || CurrentlyPlaying == P_WAV || (CurrentlyPlaying == P_MP3 && Option.AUDIO_MISO_PIN) ||CurrentlyPlaying == P_MIDI){ if(swingbuf==2){ bcount[1]=(volatile unsigned int)onRead(NULL,sbuff1,WAV_BUFFER_SIZE); wav_filesize = bcount[1]; } else { bcount[2]=(volatile unsigned int)onRead(NULL,sbuff2,WAV_BUFFER_SIZE); wav_filesize = bcount[2]; } nextbuf=swingbuf; diskchecktimer=DISKCHECKRATE; } else if(CurrentlyPlaying == P_MOD){ if(swingbuf==2){ if(hxcmod_fillbuffer( mcontext, (msample*)sbuff1, WAV_BUFFER_SIZE/4,NULL, noloop ))playreadcomplete = 1; wav_filesize=WAV_BUFFER_SIZE; bcount[1]=WAV_BUFFER_SIZE; } else { if(hxcmod_fillbuffer( mcontext, (msample*)sbuff2, WAV_BUFFER_SIZE/4,NULL, noloop ))playreadcomplete = 1; wav_filesize=WAV_BUFFER_SIZE; bcount[2]=WAV_BUFFER_SIZE; } nextbuf=swingbuf; } } else { if(CurrentlyPlaying == P_FLAC){ if(swingbuf==2){ bcount[1]=(volatile unsigned int)drflac_read_pcm_frames_s16(myflac, FLAC_BUFFER_SIZE/4, (drwav_int16*)sbuff1) * myflac->channels; if(Option.audio_i2s_bclk) i2sconvert((drwav_int16*)sbuff1,(drwav_int16*)sbuff1,bcount[1]); else iconvert(ubuff1, (int16_t *)sbuff1, bcount[1]); wav_filesize = bcount[1]; } else { bcount[2]=(volatile unsigned int)drflac_read_pcm_frames_s16(myflac, FLAC_BUFFER_SIZE/4, (drwav_int16*)sbuff2) * myflac->channels; if(Option.audio_i2s_bclk) i2sconvert((drwav_int16*)sbuff2,(drwav_int16*)sbuff2,bcount[2]); else iconvert(ubuff2, (int16_t *)sbuff2, bcount[2]); wav_filesize = bcount[2]; } nextbuf=swingbuf; #ifdef rp2350 } else if(CurrentlyPlaying == P_MP3){ if(swingbuf==2){ bcount[1]=drmp3_read_pcm_frames_s16(mymp3, MP3_BUFFER_SIZE/4, (int16_t *)sbuff1) * mymp3->channels; if(!Option.audio_i2s_bclk)iconvert(ubuff1, (int16_t *)sbuff1, bcount[1]); else i2sconvert(g_buff1, (int16_t *)sbuff1, bcount[1]); wav_filesize = bcount[1]; } else { bcount[2]=drmp3_read_pcm_frames_s16(mymp3, MP3_BUFFER_SIZE/4, (int16_t *)sbuff2) * mymp3->channels; if(!Option.audio_i2s_bclk)iconvert(ubuff2, (int16_t *)sbuff2, bcount[2]); else i2sconvert(g_buff2, (int16_t *)sbuff2, bcount[2]); wav_filesize = bcount[2]; } nextbuf=swingbuf; #endif } else if(CurrentlyPlaying == P_MOD){ if(swingbuf==2){ if(hxcmod_fillbuffer( mcontext, (msample*)sbuff1, MOD_BUFFER_SIZE/4,NULL, noloop ))playreadcomplete = 1; wav_filesize=MOD_BUFFER_SIZE/2; bcount[1]=MOD_BUFFER_SIZE/2; if(Option.audio_i2s_bclk)i2sconvert(g_buff1, (int16_t *)sbuff1, bcount[1]); else iconvert((uint16_t *)ubuff1, (int16_t *)sbuff1, bcount[1]); } else { if(hxcmod_fillbuffer( mcontext, (msample*)sbuff2, MOD_BUFFER_SIZE/4,NULL, noloop ))playreadcomplete = 1; wav_filesize=MOD_BUFFER_SIZE/2; bcount[2]=MOD_BUFFER_SIZE/2; if(Option.audio_i2s_bclk)i2sconvert(g_buff2, (int16_t *)sbuff2, bcount[2]); else iconvert((uint16_t *)ubuff2, (int16_t *)sbuff2, bcount[2]); } nextbuf=swingbuf; } else if(CurrentlyPlaying == P_WAV){ if(swingbuf==2){ bcount[1]=(volatile unsigned int)drwav_read_pcm_frames_s16(mywav, WAV_BUFFER_SIZE/4, (drwav_int16*)sbuff1) * mywav->channels; if(Option.audio_i2s_bclk) i2sconvert(g_buff1,(drwav_int16*)sbuff1,bcount[1]); else iconvert(ubuff1, (int16_t *)sbuff1, bcount[1]); wav_filesize = bcount[1]; } else { bcount[2]=(volatile unsigned int)drwav_read_pcm_frames_s16(mywav, WAV_BUFFER_SIZE/4, (drwav_int16*)sbuff2) * mywav->channels; if(Option.audio_i2s_bclk) i2sconvert(g_buff2,(drwav_int16*)sbuff2,bcount[2]); else iconvert(ubuff2, (int16_t *)sbuff2, bcount[2]); wav_filesize = bcount[2]; } nextbuf=swingbuf; diskchecktimer=DISKCHECKRATE; } } } if(wav_filesize<=0 && (CurrentlyPlaying == P_WAV || (CurrentlyPlaying == P_FLAC)|| (CurrentlyPlaying == P_MP3) || (CurrentlyPlaying == P_MIDI))){ if(trackplaying==trackstoplay) { playreadcomplete=1; } else { if(CurrentlyPlaying == P_WAV){ trackplaying++; wavcallback(alist[trackplaying].fn); } else if(CurrentlyPlaying == P_FLAC){ trackplaying++; flaccallback(alist[trackplaying].fn); } else if(CurrentlyPlaying == P_MP3){ trackplaying++; mp3callback(alist[trackplaying].fn,0); } else if(CurrentlyPlaying == P_MIDI){ if(Option.AUDIO_MISO_PIN && VSbuffer>32)return; trackplaying++; midicallback(alist[trackplaying].fn); } } } } void audio_checks(void){ if(playreadcomplete == 1) { if(!(bcount[1] || bcount[2]) ){ if(Option.AUDIO_MISO_PIN && VSbuffer>32)return; if(CurrentlyPlaying == P_FLAC)drflac_close(myflac); if(CurrentlyPlaying == P_MOD)FreeMemory((void *)mcontext); if(CurrentlyPlaying == P_WAV)FreeMemorySafe((void **)&mywav); #ifdef rp2350 if(CurrentlyPlaying == P_MP3 && Option.AUDIO_MISO_PIN==0){ drmp3_uninit(mymp3); FreeMemorySafe((void **)&mymp3); } #endif FreeMemorySafe((void **)&sbuff1); FreeMemorySafe((void **)&sbuff2); FreeMemorySafe((void **)&alist); if(Option.AUDIO_MISO_PIN){ pwm_set_irq0_enabled(AUDIO_SLICE, false); CurrentlyPlaying = P_NOTHING; } else StopAudio(); FileClose(WAV_fnbr); WAVcomplete = true; // playreadcomplete = 0; } } } /* @endcond */