⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 webradio.c

📁 qt91上实现的mp3播放机,支持sam9260,参考用
💻 C
字号:
/*!
 * Copyright (C) 2006-2007 by egnite Software GmbH. 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. Neither the name of the copyright holders nor the names of
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
 * ``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 EGNITE
 * SOFTWARE GMBH OR CONTRIBUTORS 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.
 *
 * For additional information see http://www.ethernut.de/
 */

/*!
 * \file webradio.c
 * \brief Internet radio main file.
 *
 * \verbatim
 *
 * $Log$
 *
 * \endverbatim
 */


/*
 * Limited AT91SAM9260-EK MP3 player sample.
 *
 * Will sequentially play all MP3 files from an MMC's root directory.
 *
 * MultiMedia Cards only, no SD Cards (see arch/arm/dev/at91_mmc.c).
 * Root directory must contain MP3 files only.
 * Hardcoded for 180MHz CPU clock and 44.1kHz sampling rate (also see ./at73dac.c).
 */

#include <cfg/os.h>
#include <cfg/clock.h>
#include <dev/board.h>
#include <dev/st7036.h>

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <fcntl.h>
#include <io.h>

#include <sys/version.h>
#include <sys/confnet.h>
#include <sys/atom.h>
#include <sys/heap.h>
#include <sys/thread.h>
#include <sys/timer.h>
#include <sys/event.h>
#include <sys/socket.h>

#include <hxmp3/mp3dec.h>

#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <net/route.h>

#include <pro/dhcp.h>
#include <pro/sntp.h>
#include <pro/discover.h>

#include "tlv320dac.h"
#include "config.h"
#include "shoutcast.h"
#include "player.h"
#include "httpserv.h"
#include "userif.h"

/*
 * Unique MAC address of the Ethernut Board.
 *
 * Ignored if EEPROM contains a valid configuration.
 */
#define MY_MAC { 0x00, 0x06, 0x98, 0x30, 0x00, 0x35 }

/*
 * Unique IP address of the Ethernut Board.
 *
 * Ignored if DHCP is used.
 */
#define MY_IPADDR "192.168.192.35"

/*
 * IP network mask of the Ethernut Board.
 *
 * Ignored if DHCP is used.
 */
#define MY_IPMASK "255.255.255.0"

/*
 * Gateway IP address for the Ethernut Board.
 *
 * Ignored if DHCP is used.
 */
#define MY_IPGATE "192.168.192.1"

/*
 * Wether we should run a discovery responder.
 */
#if defined(AT91SAM9260_EK)
#define USE_DISCOVERY
#endif

/*
 * IP address of the host running a time daemon. 
 */
#if defined(AT91SAM9260_EK)
//#define MY_TIMED "130.149.17.21"
#endif

/*
 * Local timezone, -1 for Central Europe. 
 */
#ifndef MY_TZ
#define MY_TZ    -1
#endif

RADIOCONTROL radio;

/*
 * Query a time server and optionally update the hardware clock.
 */
static int QueryTimeServer(void)
{
    int rc = -1;

#ifdef MY_TIMED
    int retries = 5;

    _timezone = MY_TZ * 60L * 60L;
    while (retries--) {
        time_t now;
        u_long timeserver = inet_addr(MY_TIMED);

        /* Query network time service and set the system time. */
        printf("Query time from %s...", MY_TIMED);
        if(NutSNTPGetTime(&timeserver, &now) == 0) {
            puts("OK");
            rc = 0;
            stime(&now);
            break;
        }
        else {
            puts("failed");
        }
    }
#endif

    return rc;
}

int InitEthernetDevice(void)
{
    u_long ip_addr = inet_addr(MY_IPADDR);
    u_long ip_mask = inet_addr(MY_IPMASK);
    u_long ip_gate = inet_addr(MY_IPGATE);
    u_char mac[6] = MY_MAC;

    for (;;) {
        printf("Register %s...", DEV_ETHER_NAME);
        if (NutRegisterDevice(&DEV_ETHER, 0x8300, 5) == 0) {
            puts("OK");
            break;
        }
        puts("No Ethernet, retry");
    }

    printf("Configure %s...", DEV_ETHER_NAME);
    if (NutDhcpIfConfig(DEV_ETHER_NAME, 0, 60000) == 0) {
        puts("OK");
        return 0;
    }
    printf("initial boot...");
    if (NutDhcpIfConfig(DEV_ETHER_NAME, mac, 60000) == 0) {
        puts("OK");
        return 0;
    }
    printf("No DHCP...");
    NutNetIfConfig(DEV_ETHER_NAME, mac, ip_addr, ip_mask);
    /* Without DHCP we had to set the default gateway manually.*/
    if(ip_gate) {
        printf("hard coded gate...");
        NutIpRouteAdd(0, 0, ip_gate, &DEV_ETHER);
    }
    puts("OK");

    return 0;
}

/*!
 * \brief Main application routine.
 */
int main(void)
{
    u_long baud = 115200;
    u_long ipgate;
    u_int failcnt = 0;

    /*
     * Register and open the DBGU device, which we will use for debug 
     * output via stdout.
     */
    NutRegisterDevice(&DEV_DEBUG, 0, 0);
    freopen(DEV_DEBUG_NAME, "w", stdout);
    _ioctl(_fileno(stdout), UART_SETSPEED, &baud);

    /*
     * Display some general information.
     */
    printf("\n\nSAM Internet Radio %s - Nut/OS %s\n", VERSION, NutVersionString());
    printf("%u bytes free\n", (u_int)NutHeapAvailable());
    printf("CPU Clock   : %lu\n", NutGetCpuClock());
    printf("Master Clock: %lu\n", At91GetMasterClock());

    /*
     * Initialize the user interface, LCD and 3 buttons.
     */
    if (NutRegisterDevice(&devSbiLcd, 0, 0)) {
        puts("Failed to register LCD");
    }
    if (UserIfInit("sbilcd")) {
        puts("LCD init failure\n");
    }

    /* 
     * Initialize the Ethernet device and print our IP setting. 
     */
    InitEthernetDevice();
    printf("IP Addr: %s\n", inet_ntoa(confnet.cdn_ip_addr));
    printf("IP Mask: %s\n", inet_ntoa(confnet.cdn_ip_mask));
    NutIpRouteQuery(0, &ipgate);
    printf("IP Gate: %s\n", inet_ntoa(ipgate));

    /* 
     * Register a discovery responder. This optional feature
     * allows to discover all Nut/OS devices in a local network.
     */
#ifdef USE_DISCOVERY
    printf("Start Responder...");
    if (NutRegisterDiscovery((u_long)-1, 0, DISF_INITAL_ANN)) {
        puts("failed");
    }
    else {
        puts("OK");
    }
#endif

    /*
     * Try to get current date and time from an SNTP server.
     */
    if (QueryTimeServer() == 0) {
        time_t now = time(0);
        struct _tm *lot = localtime(&now);
        printf("Date: %02u.%02u.%u\n", lot->tm_mday, lot->tm_mon + 1, 1900 + lot->tm_year);
        printf("Time: %02u:%02u:%02u\n", lot->tm_hour, lot->tm_min, lot->tm_sec);
#ifdef USE_HTTPSERVER
        h_timevalid = 1;
#endif
    }

#ifdef USE_HTTPSERVER
    HttpServerStart();
#endif

    ConfigResetFactory();

    /*
     * Create all required receiver and player instances.
     */
    radio.rc_rip = ReceiverCreate(&rpiShoutcast);
    radio.rc_pip = PlayerCreate(&ppiMp3);

    /*
     * Never ending application loop.
     */
    for (;;) {
        if (failcnt > 3) {
            printf("Too many failures. Select next station.\n");
            radio.rc_rstation = StationSelect(radio.rc_cstation, 1);
            failcnt = 0;
        }
        radio.rc_cstation = radio.rc_rstation;
        printf("Trying station entry %u\n", radio.rc_cstation);

        /*
         * Connect station.
         */
        UserIfShowStatus(DIST_CONNECTING);
        radio.rc_sip = StationConnect(&station[radio.rc_cstation]);
        if (radio.rc_sip == NULL) {
            /* Connection failed. */
            UserIfShowStatus(DIST_DEAD);
            NutSleep(1000);
            radio.rc_rstation = StationSelect(radio.rc_cstation, 0);
            failcnt++;
            continue;
        }

        /*
         * Station connected.
         */
        printf("Connected: %u bytes free\n", (u_int)NutHeapAvailable());
        if (ReceiverStart(radio.rc_rip, radio.rc_sip) == 0) {
            UserIfShowStatus(DIST_CONNECTED);
            if (radio.rc_sip->si_ptype == PLAYER_TYPE_MP3) {
                if (PlayerStart(radio.rc_pip, radio.rc_rip) == 0) {
                    failcnt = 0;
                    NutSleep(1000);
                    while (radio.rc_cstation == radio.rc_rstation) {
                        if (PlayerStatus(radio.rc_pip) != PSTAT_RUNNING) {
                            radio.rc_rstation = StationSelect(radio.rc_cstation, 0);
                            failcnt++;
                            break;
                        }
                        NutSleep(1000);
                    }
                    printf("\nStop player ");
                    PlayerStop(radio.rc_pip);
                }
                else {
                    radio.rc_rstation = StationSelect(radio.rc_cstation, 0);
                    failcnt++;
                }
            }
            else {
                printf("Bad content type\n");
                radio.rc_rstation = StationSelect(radio.rc_cstation, 0);
                failcnt++;
            }
            printf("\nStop receiver ");
            ReceiverStop(radio.rc_rip);
        }
        else {
            radio.rc_rstation = StationSelect(radio.rc_cstation, 0);
            failcnt++;
        }
        printf("\nDisconnect station ");
        StationDisconnect(radio.rc_sip);
        radio.rc_sip = NULL;
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -