void WriteWave(const char *wavFile, short *waveData, int numSamples, int sampleRate) { FILE *wavFp; WavFileHead wavHead; long numWrite; wavFp = fopen(wavFile, "wb"); if (!wavFp) { printf("\nERROR:can't open %s!\n", wavFile); exit(0); } FillWaveHeader(&wavHead, numSamples*sizeof(short), sampleRate); fwrite(&wavHead, sizeof(WavFileHead), 1, wavFp); numWrite = fwrite(waveData, sizeof(short), numSamples, wavFp); assert(numWrite == numSamples); fclose(wavFp); }
/***************************************************************************************** Primary query function *****************************************************************************************/ int CAPEInfo::GetInfo(APE_DECOMPRESS_FIELDS Field, int nParam1, int nParam2) { int nRetVal = -1; switch (Field) { case APE_INFO_FILE_VERSION: nRetVal = m_APEFileInfo.nVersion; break; case APE_INFO_COMPRESSION_LEVEL: nRetVal = m_APEFileInfo.nCompressionLevel; break; case APE_INFO_FORMAT_FLAGS: nRetVal = m_APEFileInfo.nFormatFlags; break; case APE_INFO_SAMPLE_RATE: nRetVal = m_APEFileInfo.nSampleRate; break; case APE_INFO_BITS_PER_SAMPLE: nRetVal = m_APEFileInfo.nBitsPerSample; break; case APE_INFO_BYTES_PER_SAMPLE: nRetVal = m_APEFileInfo.nBytesPerSample; break; case APE_INFO_CHANNELS: nRetVal = m_APEFileInfo.nChannels; break; case APE_INFO_BLOCK_ALIGN: nRetVal = m_APEFileInfo.nBlockAlign; break; case APE_INFO_BLOCKS_PER_FRAME: nRetVal = m_APEFileInfo.nBlocksPerFrame; break; case APE_INFO_FINAL_FRAME_BLOCKS: nRetVal = m_APEFileInfo.nFinalFrameBlocks; break; case APE_INFO_TOTAL_FRAMES: nRetVal = m_APEFileInfo.nTotalFrames; break; case APE_INFO_WAV_HEADER_BYTES: nRetVal = m_APEFileInfo.nWAVHeaderBytes; break; case APE_INFO_WAV_TERMINATING_BYTES: nRetVal = m_APEFileInfo.nWAVTerminatingBytes; break; case APE_INFO_WAV_DATA_BYTES: nRetVal = m_APEFileInfo.nWAVDataBytes; break; case APE_INFO_WAV_TOTAL_BYTES: nRetVal = m_APEFileInfo.nWAVTotalBytes; break; case APE_INFO_APE_TOTAL_BYTES: nRetVal = m_APEFileInfo.nAPETotalBytes; break; case APE_INFO_TOTAL_BLOCKS: nRetVal = m_APEFileInfo.nTotalBlocks; break; case APE_INFO_LENGTH_MS: nRetVal = m_APEFileInfo.nLengthMS; break; case APE_INFO_AVERAGE_BITRATE: nRetVal = m_APEFileInfo.nAverageBitrate; break; case APE_INFO_FRAME_BITRATE: { int nFrame = nParam1; nRetVal = 0; int nFrameBytes = GetInfo(APE_INFO_FRAME_BYTES, nFrame); int nFrameBlocks = GetInfo(APE_INFO_FRAME_BLOCKS, nFrame); if ((nFrameBytes > 0) && (nFrameBlocks > 0) && m_APEFileInfo.nSampleRate > 0) { int nFrameMS = (nFrameBlocks * 1000) / m_APEFileInfo.nSampleRate; if (nFrameMS != 0) { nRetVal = (nFrameBytes * 8) / nFrameMS; } } break; } case APE_INFO_DECOMPRESSED_BITRATE: nRetVal = m_APEFileInfo.nDecompressedBitrate; break; case APE_INFO_PEAK_LEVEL: nRetVal = -1; // no longer supported break; case APE_INFO_SEEK_BIT: { int nFrame = nParam1; if (GET_FRAMES_START_ON_BYTES_BOUNDARIES(this)) { nRetVal = 0; } else { if (nFrame < 0 || nFrame >= m_APEFileInfo.nTotalFrames) nRetVal = 0; else nRetVal = m_APEFileInfo.spSeekBitTable[nFrame]; } break; } case APE_INFO_SEEK_BYTE: { int nFrame = nParam1; if (nFrame < 0 || nFrame >= m_APEFileInfo.nTotalFrames) nRetVal = 0; else nRetVal = m_APEFileInfo.spSeekByteTable[nFrame] + m_APEFileInfo.nJunkHeaderBytes; break; } case APE_INFO_WAV_HEADER_DATA: { char * pBuffer = (char *) nParam1; int nMaxBytes = nParam2; if (m_APEFileInfo.nFormatFlags & MAC_FORMAT_FLAG_CREATE_WAV_HEADER) { if (sizeof(WAVE_HEADER) > static_cast<uint32>(nMaxBytes)) { nRetVal = -1; } else { WAVEFORMATEX wfeFormat; GetInfo(APE_INFO_WAVEFORMATEX, (int) &wfeFormat, 0); WAVE_HEADER WAVHeader; FillWaveHeader(&WAVHeader, m_APEFileInfo.nWAVDataBytes, &wfeFormat, m_APEFileInfo.nWAVTerminatingBytes); memcpy(pBuffer, &WAVHeader, sizeof(WAVE_HEADER)); nRetVal = 0; } } else { if (m_APEFileInfo.nWAVHeaderBytes > nMaxBytes) { nRetVal = -1; } else { memcpy(pBuffer, m_APEFileInfo.spWaveHeaderData, m_APEFileInfo.nWAVHeaderBytes); nRetVal = 0; } } break; } case APE_INFO_WAV_TERMINATING_DATA: { char * pBuffer = (char *) nParam1; int nMaxBytes = nParam2; if (m_APEFileInfo.nWAVTerminatingBytes > nMaxBytes) { nRetVal = -1; } else { if (m_APEFileInfo.nWAVTerminatingBytes > 0) { // variables int nOriginalFileLocation = m_spIO->GetPosition(); unsigned int nBytesRead = 0; // check for a tag m_spIO->Seek(-(m_spAPETag->GetTagBytes() + m_APEFileInfo.nWAVTerminatingBytes), FILE_END); m_spIO->Read(pBuffer, m_APEFileInfo.nWAVTerminatingBytes, &nBytesRead); // restore the file pointer m_spIO->Seek(nOriginalFileLocation, FILE_BEGIN); } nRetVal = 0; } break; } case APE_INFO_WAVEFORMATEX: { WAVEFORMATEX * pWaveFormatEx = (WAVEFORMATEX *) nParam1; FillWaveFormatEx(pWaveFormatEx, m_APEFileInfo.nSampleRate, m_APEFileInfo.nBitsPerSample, m_APEFileInfo.nChannels); nRetVal = 0; break; } case APE_INFO_IO_SOURCE: nRetVal = (int) m_spIO.GetPtr(); break; case APE_INFO_FRAME_BYTES: { int nFrame = nParam1; // bound-check the frame index if ((nFrame < 0) || (nFrame >= m_APEFileInfo.nTotalFrames)) { nRetVal = -1; } else { if (nFrame != (m_APEFileInfo.nTotalFrames - 1)) nRetVal = GetInfo(APE_INFO_SEEK_BYTE, nFrame + 1) - GetInfo(APE_INFO_SEEK_BYTE, nFrame); else nRetVal = m_spIO->GetSize() - m_spAPETag->GetTagBytes() - m_APEFileInfo.nWAVTerminatingBytes - GetInfo(APE_INFO_SEEK_BYTE, nFrame); } break; } case APE_INFO_FRAME_BLOCKS: { int nFrame = nParam1; // bound-check the frame index if ((nFrame < 0) || (nFrame >= m_APEFileInfo.nTotalFrames)) { nRetVal = -1; } else { if (nFrame != (m_APEFileInfo.nTotalFrames - 1)) nRetVal = m_APEFileInfo.nBlocksPerFrame; else nRetVal = m_APEFileInfo.nFinalFrameBlocks; } break; } case APE_INFO_TAG: nRetVal = (int) m_spAPETag.GetPtr(); break; case APE_INTERNAL_INFO: nRetVal = (int) &m_APEFileInfo; break; default: nRetVal=0; } return nRetVal; }
/****************************************************************************** * @name Shell_play * * @brief Servers the play command * * @param None * * @return None * ****************************************************************************** * This function is used to play an audio wav file *****************************************************************************/ int32_t Shell_play(int32_t argc, char *argv[]) { bool print_usage, shorthelp = FALSE; uint8_t bSamFreqType_index; print_usage = Shell_check_help_request (argc, argv, &shorthelp); if (!print_usage) { WAVE_FILE_HEADER header; if (argc > 1) { /* stop the current file playing */ if(AUDIO_PLAYING == audio_state) { audio_state = AUDIO_IDLE; hwtimer_stop(&audio_timer); } /* check the device is connected */ if ((USB_DEVICE_INUSE != audio_stream.DEV_STATE)||(device_direction != USB_AUDIO_DEVICE_DIRECTION_IN)) { printf(" Error: Audio Speaker is not connected\n"); return (SHELL_EXIT_ERROR); } if (FillWaveHeader(argv[1], &header) != 0) { printf(" Error: Unable to open file: %s\n", argv[1]); return (SHELL_EXIT_ERROR); } if (strcmp(header.CHUNK_DESCRIPTOR.Format, "WAVE")) { printf(" Error: File is not WAVE file.\n"); return (SHELL_EXIT_ERROR); } if (strcmp(header.FMT_SUBCHUNK.Subchunk1ID, "fmt ")) { printf(" Error: File does not contain format subchunk.\n"); } if (BYTESWAP16(header.FMT_SUBCHUNK.AudioFormat) != 1) { printf(" Error: File is compressed (not PCM).\n"); return (SHELL_EXIT_ERROR); } if (strcmp(header.DATA_SUBCHUNK.Subchunk2ID, "data")) { printf(" Error: File does not contain data subchunk.\n"); return (SHELL_EXIT_ERROR); } file_ptr = fopen(argv[1], "r"); if (file_ptr == NULL) { printf(" Unable to open file: %s\n", argv[1]); return (SHELL_EXIT_ERROR); } file_open_count ++; printf("Audio file properties:\n"); printf(" - Sample rate : %d Hz\n", BYTESWAP32(header.FMT_SUBCHUNK.SampleRate)); printf(" - Sample size : %d bits\n", BYTESWAP16(header.FMT_SUBCHUNK.BitsPerSample)); printf(" - Number of channels : %d channels\n", BYTESWAP16(header.FMT_SUBCHUNK.NumChannels)); /* Compare the sample rate */ for (bSamFreqType_index =0; bSamFreqType_index < frm_type_desc->bSamFreqType; bSamFreqType_index++) { if (((frm_type_desc->tSamFreq[3*bSamFreqType_index + 2] << 16) | (frm_type_desc->tSamFreq[3*bSamFreqType_index + 1] << 8) | (frm_type_desc->tSamFreq[3*bSamFreqType_index] << 0)) == BYTESWAP32(header.FMT_SUBCHUNK.SampleRate)) { packet_size = USB_Audio_Get_Packet_Size(frm_type_desc,bSamFreqType_index); break; } } if (bSamFreqType_index == frm_type_desc->bSamFreqType) { printf(" The audio device doesn't support that audio sample rate \n"); return (SHELL_EXIT_ERROR); } /* Compare the bits sample number */ if (frm_type_desc->bBitResolution != BYTESWAP16(header.FMT_SUBCHUNK.BitsPerSample)) { printf(" The audio device doesn't support that audio bit sample number \n"); return (SHELL_EXIT_ERROR); } /* Compare the channel number */ if (frm_type_desc->bNrChannels != BYTESWAP16(header.FMT_SUBCHUNK.NumChannels)) { printf(" The audio device doesn't support that audio channel number \n"); return (SHELL_EXIT_ERROR); } fseek(file_ptr, WAVE_HEADER_SIZE, IO_SEEK_SET); audio_state = AUDIO_PLAYING; printf(" Playing...\n"); hwtimer_start(&audio_timer); } else { if (AUDIO_PLAYING == audio_state) { printf(" The file is playing...\n"); } else if (AUDIO_PAUSE == audio_state) { audio_state = AUDIO_PLAYING; hwtimer_start(&audio_timer); printf(" Playing...\n"); } else if (AUDIO_IDLE == audio_state) { printf(" Not enough parameters.\n"); } } } else { if (shorthelp) { printf("%s <filename>\n", argv[0]); } else { printf("Usage: %s <filename>\n", argv[0]); printf(" filename = wav file to play\n"); } } return(SHELL_EXIT_SUCCESS); }