⑴ C語言文件操作:為什麼我用fgets讀取mp3再用fputs寫到其他MP3文件中,得到一個不能播放的MP3文件
#include <stdio.h>
int main()
{
FILE *pf=fopen("1.MP3","rb");
FILE *pf1=fopen("2.MP3","wb");
char buf[1024];
while(!feof(pf))
{
memset(buf,0,1024);
fread(buf,1,1024,pf);
fwrite(buf,1,1024,pf1);
}
fclose(pf);
fclose(pf1);
return 0;
}
你在試下,肯定行!
fgets函數的作用是從指定文件讀入一個字元串。例如:
fgets(str,n,fp);
n為要求得到的字元,但只從fp指向的文件輸入n-1個字元,然後在最後加一個'\0'字元,因此得到的字元串共有n個字元,把他們放到字元數組str中。如果在讀完n-1個字元之前遇到換行符或EOF,讀入結束。fgets函數返回值為str的首地址。
fputs函數的作用是向指定的文件輸入一個字元串。例如:
fputs("China",fp);
把字元串「China」輸出到fp指向的文件。fputs函數中第一個參數可以是字元串常量、字元數組名或字元型指針。字元串末尾的'\0'不輸出。若輸出成功,函數值為0;失敗時,為EOF。
還有在使用完一個文件後應該用fclose函數關閉它,否則會造成文件丟失數據。
⑵ c語言程序設計MP3或MP4文件基本信息的解析
找了個看了下,comment是29個位元組。
可參考 http://www.chineselinuxuniversity.net/articles/27374.shtml
拿VC的C語言寫了下:
頭文件:
#include <stdio.h>
// TODO: reference additional headers your program requires here
#define MP3_ID3_LENGTH 10
typedef struct tag_ID3_INFO
{
} ID3_INFO;
#define IDENTIFY_LEN 3
#define TITLE_LEN 30
#define ARTIST_LEN 30
#define ALBUM_LEN 30
#define YEAR_LEN 4
#define COMMENT_LEN 30
#define GENRE_LEN 1
// IDENTIFY_LEN + TITLE_LEN +...
#define MP3_INFO_LENGTH 128
typedef struct tag_MP3_INFO
{
char Identify[IDENTIFY_LEN + 1]; //TAG三個字母
//這里可以用來鑒別是不是文件信息內容
char Title[TITLE_LEN + 1]; //歌曲名,30個位元組
char Artist[ARTIST_LEN + 1]; //歌手名,30個位元組
char Album[ARTIST_LEN + 1]; //所屬唱片,30個位元組
char Year[YEAR_LEN + 1]; //年,4個位元組
char Comment[COMMENT_LEN + 1]; //注釋,28個位元組
char Genre[GENRE_LEN + 1]; //類型 ,1個位元組
} MP3_INFO;
C文件:
#include <string.h>
#define MP3_OK 1
#define MP3_ERROR 1
FILE *OpenMp3File(char *pFileName);
int ReadMP3Info(FILE *pFile, MP3_INFO *pstInfo);
int OutputMP3Info(MP3_INFO *pstMp3Info);
int main(int argc, char* argv[])
{
FILE *pFile = NULL;
MP3_INFO stMp3Info = {0};
char *pfname = "E:\\Project\\MP3\\test.MP3";
pFile = OpenMp3File(pfname);
if (NULL == pFile)
{
return MP3_ERROR;
}
ReadMP3Info(pFile, &stMp3Info);
printf("\r\nMP3 file: %s", pfname);
OutputMP3Info(&stMp3Info);
printf("Hello World!\n");
return MP3_OK;
}
FILE *OpenMp3File(char *pFileName)
{
FILE *pFile = NULL;
pFile = fopen(pFileName,"rb");
if (NULL==pFile)
{
printf("open read file error!!");
return NULL;
}
return pFile;
}
int ReadMP3Info(FILE *pFile, MP3_INFO *pstInfo)
{
int len = 0;
if ((NULL == pFile) || (NULL == pstInfo))
{
return MP3_ERROR;
}
fseek(pFile, 0, SEEK_END);
len = ftell(pFile);
if (len <= (MP3_INFO_LENGTH + MP3_ID3_LENGTH))
{
return MP3_ERROR;
}
memset(pstInfo, 0, sizeof(MP3_INFO));
fseek(pFile, -MP3_INFO_LENGTH, SEEK_END);
len = fread((char *)(pstInfo->Identify), 1, IDENTIFY_LEN, pFile);
len += fread((char *)(pstInfo->Title), 1, TITLE_LEN, pFile);
len += fread((char *)(pstInfo->Artist), 1, ARTIST_LEN, pFile);
len += fread((char *)(pstInfo->Album), 1, ALBUM_LEN, pFile);
len += fread((char *)(pstInfo->Year), 1, YEAR_LEN, pFile);
len += fread((char *)(pstInfo->Comment), 1, COMMENT_LEN, pFile);
len += fread((char *)(pstInfo->Genre), 1, GENRE_LEN, pFile);
if (MP3_INFO_LENGTH != len)
{
return MP3_ERROR;
}
return MP3_OK;
}
int OutputMP3Info(MP3_INFO *pstMp3Info)
{
printf("\r\nTag : %s", pstMp3Info->Identify);
printf("\r\nTitle : %s", pstMp3Info->Title);
printf("\r\nArtist : %s", pstMp3Info->Artist);
printf("\r\nAlbum : %s", pstMp3Info->Album);
printf("\r\nYear : %s", pstMp3Info->Year);
printf("\r\nComment: %s", pstMp3Info->Comment);
return MP3_OK;
}
測試:
MP3 file: E:\Project\MP3\test.MP3
Tag : TAG
Title : TrackTitle
Artist : ArtistName
Album : AlbumTitle
Year : 2012
Comment: This is a comment
⑶ 怎麼用c語言打開一個MP3文件(直接給代碼),需要什麼軟體進行輸入
播放mp3? 那可麻煩了. 系統提供的函數只能播放wav格式.而mp3 ,ogg 等格式是壓縮格式.所以你要先下載MP3官網提供的解碼庫...
而後需要再配合本地的播放庫.比如openal ,directsound 等.
具體編程原理嘛,就是打開一個mp3文件.讀取裡面的壓縮數據流. 解析成對應碼率的wav數據流,然後送到openal里,
我的demo里是在openal里開啟4個緩沖buffer隊列,你把wav數據依次放入這4個buffer里.播放完的buffer自動排到空閑列表裡,等待再次投放數據.
⑷ 用c語言獲取wav或mp3的播放時間
#include <mmsystem.h>//包括多媒體API,標准c語言沒有相關介面函數
unsigned char str[256];
sprintf(timebuffer,"status %s position",MusicName);//timebuffer輸出緩存區,格式字元串到timebuffer,MusicName為播版放歌曲的完整路徑權
mciSendString(Music,str,256,NULL);//獲取時間,單位為毫秒
curtime=atoi(str)/1000;//單位化為秒,後面可以根據需要處理時間
⑸ 怎麼用c語言打開一個MP3文件(直接給代碼),需要什麼軟體進行輸入
VC++中播放聲音的方法
2009-09-23 14:58
聲音是多媒體的一個重要組成部分,在應用程序中加入聲音可以使界面更友好。在VC++中可以根據不同的應用要求,用不同的方法實現聲音的播放。
一.播放聲音文件的簡單方法
在VC++ 中的多媒體動態連接庫中提供了一組與音頻設備有關的函數。利用這些函數可以方便地播放聲音。最簡單的播放聲音方法就是直接調用VC++中提供的聲音播放函數BOOL sndPlaySound ( LPCSTR lpszSound,UINT fuSound ); 或BOOL PlaySound( LPCSTR lpszSound, HMODULE hmod, DWORD fuSound );其中參數lpszSound是需要播放聲音的.WAV文件的路徑和文件名, hmod在這里為NULL,fuSound是播放聲音的標志,詳細說明請參考VC++中的幫助。 例如播放C:soundmusic.wav可以用sndPlaySound ("c:\sound\music.wav",SND_ASYNC);或PlaySound("c:\sound\music.wav",NULL, SND_ASYNC|SND_NODEFAULT );如果沒有找到music.wav文件,第一種格式將播放系統默認的聲音,第二種格式不會播放系統默認的聲音。
二.將聲音文件加入到程序中
在VC++的程序設計中,可以利用各種標準的資源,如點陣圖,菜單,對話框等。同時VC++也允許用戶自定義資源,因此我們可以將聲音文件作為用戶自定義資源加入程序資源文件中,經過編譯連接生成EXE文件,實現無.WAV文件的聲音播放。
要實現作為資源的聲音文件的播放,首先要在資源管理器中加入待播放的聲音文件(實現過程並不復雜,這里不在敘述)。假設生成的聲音文件資源標識符為IDR_WAVE1。在播放時只需要調用下面的語句:
PlaySound(MAKEINTRESOURCE(IDR_WAVE1),AfxGetResourceHandle(), SND_ASYNC|SND_RESOURCE|SND_NODEFAULT|SND_LOOP);
其中MAKEINTRESOURCE()宏將整數資源標識符轉變為字元串,AfxGetResourceHandle()函數返回包含資源的模塊句柄,
SND_RESOURCE是必須的標志。
作為資源的聲音文件的第二種播放方法是把資源讀入內存後作為內存數據播放。具體步驟入下:
1.獲得包含資源的模塊句柄:
HMODULE hmod=AfxGetResourceHandle();
2.檢索資源塊信息:
HRSRC hSndResource=FindResource(hmod,MAKEINTRESOURCE(IDR_WAVE1),_T("WAVE"));
3. 裝載資源數據並加鎖:
HGLOBAL hGlobalMem=LoadResource(hmod,hSndResource);
LPCTSTR lpMemSound=(LPCSTR)LockResource(hGlobalMem);
4.播放聲音文件:
sndPlaySound(lpMemSound,SND_MEMORY));
5.釋放資源句柄:
FreeResource(hGlobalMem);
三.播放聲音文件的高級方法
在VC++中提供了一組對音頻設備及多媒體文件直接進行操作的函數。利用這些函數可以靈活地對聲音文件進行各種處理。
首先介紹幾個要用到的數據結構。WAVEFORMATEX結構定義了WAVE音頻數據文件的格式。WAVEHDR結構定義了波形音頻緩沖區。讀出的數據首先要填充此緩沖區才能送音頻設備播放。WAVEOUTCAPS結構描述了音頻設備的性能。MMCKINFO結構包含了RIFF文件中一個塊的信息。詳細的說明請參考VC++中的幫助。
下面給出程序流程簡圖及程序源代碼清單,在VC++環境下可直接使用:
源程序清單如下:
LPSTR szFileName;//聲音文件名
MMCKINFO mmckinfoParent;
MMCKINFO mmckinfoSubChunk;
DWORD dwFmtSize;
HMMIO m_hmmio;//音頻文件句柄
DWORD m_WaveLong;
HPSTR lpData;//音頻數據
HANDLE m_hData;
HANDLE m_hFormat;
WAVEFORMATEX * lpFormat;
DWORD m_dwDataOffset;
DWORD m_dwDataSize;
WAVEHDR pWaveOutHdr;
WAVEOUTCAPS pwoc;
HWAVEOUT hWaveOut;
//打開波形文件
if(!(m_hmmio=mmioOpen(szFileName,NULL,MMIO_READ|MMIO_ALLOCBUF)))
{
//File open Error
Error("Failed to open the file.");//錯誤處理函數
return false;
}
//檢查打開文件是否是聲音文件
mmckinfoParent.fccType =mmioFOURCC('W','A','V','E');
if(mmioDescend(m_hmmio,(LPMMCKINFO)&mmckinfoParent,NULL,MMIO_FINDRIFF))
{
//NOT WAVE FILE AND QUIT
}
//尋找 'fmt' 塊
mmckinfoSubChunk.ckid =mmioFOURCC('f','m','t',' ');
if(mmioDescend(m_hmmio,&mmckinfoSubChunk,&mmckinfoParent,MMIO_FINDCHUNK))
{
//Can't find 'fmt' chunk
}
//獲得 'fmt '塊的大小,申請內存
dwFmtSize=mmckinfoSubChunk.cksize ;
m_hFormat=LocalAlloc(LMEM_MOVEABLE,LOWORD(dwFmtSize));
if(!m_hFormat)
{
//failed alloc memory
}
lpFormat=(WAVEFORMATEX*)LocalLock(m_hFormat);
if(!lpFormat)
{
//failed to lock the memory
}
if((unsigned long)mmioRead(m_hmmio,(HPSTR)lpFormat,dwFmtSize)!=dwFmtSize)
{
//failed to read format chunk
}
//離開 fmt 塊
mmioAscend(m_hmmio,&mmckinfoSubChunk,0);
//尋找 'data' 塊
mmckinfoSubChunk.ckid=mmioFOURCC('d','a','t','a');
if(mmioDescend(m_hmmio,&mmckinfoSubChunk,&mmckinfoParent,MMIO_FINDCHUNK))
{
//Can't find 'data' chunk
}
//獲得 'data'塊的大小
m_dwDataSize=mmckinfoSubChunk.cksize ;
m_dwDataOffset =mmckinfoSubChunk.dwDataOffset ;
if(m_dwDataSize==0L)
{
//no data in the 'data' chunk
}
//為音頻數據分配內存
lpData=new char[m_dwDataSize];
if(!lpData)
{
//faile
}
if(mmioSeek(m_hmmio,SoundOffset,SEEK_SET)<0)
{
//Failed to read the data chunk
}
m_WaveLong=mmioRead(m_hmmio,lpData,SoundLong);
if(m_WaveLong<0)
{
//Failed to read the data chunk
}
//檢查音頻設備,返迴音頻輸出設備的性能
if(waveOutGetDeVCaps(WAVE_MAPPER,&pwoc,sizeof(WAVEOUTCAPS))!=0)
{
//Unable to allocate or lock memory
}
//檢查音頻輸出設備是否能播放指定的音頻文件
if(waveOutOpen(&hWaveOut,DevsNum,lpFormat,NULL,NULL,CALLBACK_NULL)!=0)
{
//Failed to OPEN the wave out devices
}
//准備待播放的數據
pWaveOutHdr.lpData =(HPSTR)lpData;
pWave
OutHdr.dwBufferLength =m_WaveLong;
pWaveOutHdr.dwFlags =0;
if(waveOutPrepareHeader(hWaveOut,&pWaveOutHdr,sizeof(WAVEHDR))!=0)
{
//Failed to prepare the wave data buffer
}
//播放音頻數據文件
if(waveOutWrite(hWaveOut,&pWaveOutHdr,sizeof(WAVEHDR))!=0)
{
//Failed to write the wave data buffer
}
//關閉音頻輸出設備,釋放內存
waveOutReset(hWaveOut);
waveOutClose(hWaveOut);
LocalUnlock(m_hFormat);
LocalFree(m_hFormat);
delete [] lpData;
說明:1)以上使用的音頻設備和聲音文件操作函數的聲明包含在mmsystem.h頭文件中,因此在程序中必須用#include "mmsystem.h"語句加入頭文件。同時在編譯時要加入動態連接導入庫winmm.lib,具體實現方法是從Developer Studio的Project菜單中選擇Settings,然後在Link選項卡上的Object/Library Moles控制中加入winmm.lib。2)在pWaveOutHdr.lpData中指定不同的數據,可以播放音頻數據文件中任意指定位置的聲音。3) 以上程序均在VC++6.0中調試通過,在文中省略了對錯誤及異常情況的處理,在實際應用中必須加入。
四.結論
在VC++中可以根據應用需要採用不同的方法播放聲音文件。簡單應用可以直接調用聲音播放函數。第二種方法可以把聲音作為資源加入可執行文件中。如果在播放之前要對聲音數據進行處理,可用第三種方法。
參考書目:
1. 美 Paul Perry 陳向群 等譯《多媒體開發指南》 清華大學出版社
2. 美 Peter Norton, Rob McGregor 孫鳳英 等譯《MFC開發Windows95/NT4應用程序》 清華大學出版社 1998
3. 周敬利 《多媒體音效卡技術及應用》 電子工業出版社 1998
⑹ c語言播放MP3 API函數是什麼 怎麼用
建議參考這個:http://..com/question/41366091.html 裡面有說到如何播放mp3文件的函回數,及其答說明。
⑺ C語言如何播放mp3格式音樂
|windows現有的API似乎只支持播放.wav格式的音頻,mp3格式恐怕你得再去網上找找開源代專碼
//播放屬音頻"1.wav"
#include<stdio.h>
#include<windows.h>
#pragmacomment(lib,"winmm.lib")
intmain()
{
PlaySound("1.wav",NULL,SND_FILENAME|SND_ASYNC|SND_LOOP);
getchar();
return0;
}
⑻ c語言中怎樣實現復制MP3,求源程序
用c++很好做復,c忘了……給你制一個讀出的源碼,寫入的方式與之類似
假設源文件為s,目標緩沖區為d
================================
ifstream file(s,ios::binary) //二進制方式打開源文件
long pointer = 0; //當前復制的位置
do{
file.read(buf+pointer, DATA_SIZE); //將文件讀出至緩沖區內,每次讀取DATA_SIZE大小
pointer += DATA_SIZE;
}while(file.good()); //文件結尾
⑼ 怎樣用C語言編程打開一個文件(比如mp3,mp4)
可以使用PlaySound()函數播放mp3音頻,該函數原型位於windows.h。
PlaySound函數的聲明為:
BOOL PlaySound(LPCSTR pszSound, HMODULE hwnd,DWORD fdwSound);
參數pszSound是指定了要播放聲音的字元串。
參數hwnd是應用程序的實例句柄,除非pszSound的指向一個資源標識符(即fdwSound被定義為SND_RESOURCE),否則必須設置為NULL。
參數fdwSound是標志的組合,如下表所示。若成功則函數返回TRUE,否則返回FALSE。
使用PlaySound函數時需要在#include<windows.h>後面加上(注意:不能加在前面):
常式:
CFileDialog dlg(TRUE, "mp3", "*.mp3", OFN_HIDEREADONLY|OFN_ALLOWMULTISELECT, "mp3文件(*.mp3)|*.mp3|");
/*創建選擇對話框,讓用戶從文件夾中選取一個MP3文件*/
int iRet = dlg.DoModal();//獲得對話框返回值
if(IDOK == iRet) //如果返回值成功,表明成功獲取一個MP3文件
{
CString pathName= dlg.GetPathName(); //得到文件的路徑名稱
PlaySound( pathName , NULL, SND_FILENAME | SND_ASYNC);//用playsound函數播放該文件
}
⑽ 怎麼用C語言讀寫音樂文件
這個程序可能是最簡單的mp3播放器了。當然也談不上什麼功能。但是確實能播放。
鏈接時要指定庫文件。VC++是vfw32.lib, GCC是libvfw32.a.
我在VC6.0和GCC/MinGW 3.3.1下都通過了。
假設程序名是MyPlay, 目錄下還有一個aaa.mp3, 運行MyPlay aaa.mp3即可。
注意Sleep(50000)是讓他最多播放50秒。沒有Sleep()的話,窗口一閃就退出了。
具體的MCI函數請查有關資料。
#include <windows.h>
#include <vfw.h>
int main(int argc, char* argv[])
{
if (argc>1) {
HWND MyPlayer = MCIWndCreate(NULL,GetMoleHandle(NULL), 0, argv[1]);
MCIWndPlay(MyPlayer);
Sleep(50000);
}
return 0;
}
這個程序還可以播放MIDI, AVI, WMV, MPG等影音文件。
如果只是後台播放MIDI或MP3,不想顯示那個沒有用的窗口,把MCIWndCreate()第三個參數0改成WS_POPUP即可。
如果想精確控制Sleep()至MP3播放結束,可以改成 Sleep(MCIWndGetLength(MyPlayer));
對於mp3, MCIWndGetLength()返回值的單位是毫秒,可以直接用於Sleep()延時。
對於mpg, MCIWndGetLength()返回值的單位是幀數,還要轉換成毫秒才能用於Sleep().
具體MCIWndGetLength()返回值的單位是什麼,可以調用MCIWndGetTimeFormat()來查詢。
>是C,不是C++ 更不是Vc++
你誤解了。VC6.0不只是支持C++, 也支持C. GCC更是C編譯器,不是C++編譯器。
這個程序是地地道道的C程序,沒有一丁點兒 C++ 的成分。但是他調用了Windows API函數,所以必須用支持Windows編程的32位C編譯器,不一定用VC或GCC。
很多人認為,剛學C語言最好用GCC或VC的命令行方式,但遺憾的大多教學用的C環境仍然選用20多年前的TC。如果堅持用16位的TC可以做一些事情,但在現在絕大多數事情是他做不到的。