diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 5fcd562720..a76ab1f2c5 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -424,6 +424,16 @@ deleteAll: "全て削除"
 showFixedPostForm: "タイムライン上部に投稿フォームを表示する"
 newNoteRecived: "新しいノートがあります"
 useNotificationsPopup: "通知一覧をポップアップで表示"
+sounds: "サウンド"
+listen: "聴く"
+none: "なし"
+volume: "音量"
+
+_sfx:
+  note: "ノート"
+  notification: "通知"
+  chat: "チャット"
+  chatBg: "チャット(バックグラウンド)"
 
 _ago:
   unknown: "謎"
diff --git a/src/client/app.vue b/src/client/app.vue
index a3290486a7..cfb17c05f9 100644
--- a/src/client/app.vue
+++ b/src/client/app.vue
@@ -93,7 +93,7 @@
 					<fa :icon="faEllipsisH" fixed-width/><span class="text">{{ $t('more') }}</span>
 					<i v-if="$store.getters.isSignedIn && ($store.state.i.hasUnreadMentions || $store.state.i.hasUnreadSpecifiedNotes)"><fa :icon="faCircle"/></i>
 				</button>
-				<router-link class="item" active-class="active" to="/settings">
+				<router-link class="item" active-class="active" to="/preferences">
 					<fa :icon="faCog" fixed-width/><span class="text">{{ $t('settings') }}</span>
 				</router-link>
 			</div>
@@ -578,13 +578,19 @@ export default Vue.extend({
 
 		onNotification(notification) {
 			// TODO: ユーザーが画面を見てないと思われるとき(ブラウザやタブがアクティブじゃないなど)は送信しない
-			this.$root.stream.send('readNotification', {
-				id: notification.id
-			});
+			if (true) {
+				this.$root.stream.send('readNotification', {
+					id: notification.id
+				});
 
-			this.$root.new(MkToast, {
-				notification
-			});
+				this.$root.new(MkToast, {
+					notification
+				});
+			}
+
+			const audio = new Audio(`/assets/sounds/${this.$store.state.device.sfxNotification}.mp3`);
+			audio.volume = this.$store.state.device.sfxVolume;
+			audio.play();
 		},
 
 		onMousedown(e) {
diff --git a/src/client/assets/sounds/aisha/1.mp3 b/src/client/assets/sounds/aisha/1.mp3
new file mode 100644
index 0000000000..d8e9a2f265
Binary files /dev/null and b/src/client/assets/sounds/aisha/1.mp3 differ
diff --git a/src/client/assets/sounds/aisha/2.mp3 b/src/client/assets/sounds/aisha/2.mp3
new file mode 100644
index 0000000000..477c2eba43
Binary files /dev/null and b/src/client/assets/sounds/aisha/2.mp3 differ
diff --git a/src/client/assets/sounds/aisha/3.mp3 b/src/client/assets/sounds/aisha/3.mp3
new file mode 100644
index 0000000000..fe0d8063df
Binary files /dev/null and b/src/client/assets/sounds/aisha/3.mp3 differ
diff --git a/src/client/assets/sounds/noizenecio/kick_gaba.mp3 b/src/client/assets/sounds/noizenecio/kick_gaba.mp3
new file mode 100644
index 0000000000..616b506c4f
Binary files /dev/null and b/src/client/assets/sounds/noizenecio/kick_gaba.mp3 differ
diff --git a/src/client/assets/sounds/syuilo/pope1.mp3 b/src/client/assets/sounds/syuilo/pope1.mp3
new file mode 100644
index 0000000000..585bb0407e
Binary files /dev/null and b/src/client/assets/sounds/syuilo/pope1.mp3 differ
diff --git a/src/client/assets/sounds/syuilo/pope2.mp3 b/src/client/assets/sounds/syuilo/pope2.mp3
new file mode 100644
index 0000000000..83865b989e
Binary files /dev/null and b/src/client/assets/sounds/syuilo/pope2.mp3 differ
diff --git a/src/client/assets/sounds/syuilo/waon.mp3 b/src/client/assets/sounds/syuilo/waon.mp3
new file mode 100644
index 0000000000..c5797f066e
Binary files /dev/null and b/src/client/assets/sounds/syuilo/waon.mp3 differ
diff --git a/src/client/components/timeline.vue b/src/client/components/timeline.vue
index 407aeb2161..ba367bf23d 100644
--- a/src/client/components/timeline.vue
+++ b/src/client/components/timeline.vue
@@ -21,6 +21,11 @@ export default Vue.extend({
 		},
 		antenna: {
 			required: false
+		},
+		sound: {
+			type: Boolean,
+			required: false,
+			default: false,
 		}
 	},
 
@@ -46,6 +51,12 @@ export default Vue.extend({
 
 		const prepend = note => {
 			(this.$refs.tl as any).prepend(note);
+
+			if (this.sound) {
+				const audio = new Audio(`/assets/sounds/${this.$store.state.device.sfxNote}.mp3`);
+				audio.volume = this.$store.state.device.sfxVolume;
+				audio.play();
+			}
 		};
 
 		const onUserAdded = () => {
diff --git a/src/client/components/ui/select.vue b/src/client/components/ui/select.vue
index 3d22b8198e..6266fb5a2d 100644
--- a/src/client/components/ui/select.vue
+++ b/src/client/components/ui/select.vue
@@ -56,7 +56,7 @@ export default Vue.extend({
 			}
 		},
 		filled(): boolean {
-			return this.v != '' && this.v != null;
+			return true;
 		}
 	},
 	mounted() {
@@ -100,6 +100,7 @@ export default Vue.extend({
 
 	> .input {
 		display: flex;
+		position: relative;
 
 		&:before {
 			content: '';
diff --git a/src/client/mios.ts b/src/client/mios.ts
index 3bf026af7f..e0eb99769e 100644
--- a/src/client/mios.ts
+++ b/src/client/mios.ts
@@ -197,6 +197,10 @@ export default class MiOS extends EventEmitter {
 				this.store.dispatch('mergeMe', {
 					hasUnreadMessagingMessage: true
 				});
+
+				const audio = new Audio(`/assets/sounds/${this.store.state.device.sfxChatBg}.mp3`);
+				audio.volume = this.store.state.device.sfxVolume;
+				audio.play();
 			});
 
 			main.on('readAllAntennas', () => {
diff --git a/src/client/pages/index.home.vue b/src/client/pages/index.home.vue
index c3bc71b114..14a385d1a8 100644
--- a/src/client/pages/index.home.vue
+++ b/src/client/pages/index.home.vue
@@ -19,7 +19,7 @@
 	<x-tutorial class="tutorial" v-if="$store.state.settings.tutorial != -1"/>
 
 	<x-post-form class="post-form _panel" fixed v-if="$store.state.device.showFixedPostForm"/>
-	<x-timeline ref="tl" :key="src === 'list' ? `list:${list.id}` : src === 'antenna' ? `antenna:${antenna.id}` : src" :src="src" :list="list" :antenna="antenna" @before="before()" @after="after()" @queue="queueUpdated"/>
+	<x-timeline ref="tl" :key="src === 'list' ? `list:${list.id}` : src === 'antenna' ? `antenna:${antenna.id}` : src" :src="src" :list="list" :antenna="antenna" :sound="true" @before="before()" @after="after()" @queue="queueUpdated"/>
 </div>
 </template>
 
diff --git a/src/client/pages/messaging-room.vue b/src/client/pages/messaging-room.vue
index b2584393a0..aa0c4c93b8 100644
--- a/src/client/pages/messaging-room.vue
+++ b/src/client/pages/messaging-room.vue
@@ -185,11 +185,9 @@ export default Vue.extend({
 
 		onMessage(message) {
 			// サウンドを再生する
-			if (this.$store.state.device.enableSounds) {
-				const sound = new Audio(`${url}/assets/message.mp3`);
-				sound.volume = this.$store.state.device.soundVolume;
-				sound.play();
-			}
+			const audio = new Audio(`/assets/sounds/${this.$store.state.device.sfxChat}.mp3`);
+			audio.volume = this.$store.state.device.sfxVolume;
+			audio.play();
 
 			const isBottom = this.isBottom();
 
diff --git a/src/client/pages/settings/index.vue b/src/client/pages/preferences/index.vue
similarity index 60%
rename from src/client/pages/settings/index.vue
rename to src/client/pages/preferences/index.vue
index b3ef4d17b9..4193959188 100644
--- a/src/client/pages/settings/index.vue
+++ b/src/client/pages/preferences/index.vue
@@ -5,6 +5,36 @@
 
 	<x-theme/>
 
+	<section class="_card">
+		<div class="_title"><fa :icon="faMusic"/> {{ $t('sounds') }}</div>
+		<div class="_content">
+			{{ $t('volume') }}
+			<input type="range" v-model="sfxVolume" min="0" max="1" step="0.1"/>
+		</div>
+		<div class="_content">
+			<mk-select v-model="sfxNote">
+				<template #label>{{ $t('_sfx.note') }}</template>
+				<option v-for="sound in sounds" :value="sound" :key="sound">{{ sound || $t('none') }}</option>
+				<template #text><button class="_textButton" @click="listen(sfxNote)" v-if="sfxNote"><fa :icon="faPlay"/> {{ $t('listen') }}</button></template>
+			</mk-select>
+			<mk-select v-model="sfxNotification">
+				<template #label>{{ $t('_sfx.notification') }}</template>
+				<option v-for="sound in sounds" :value="sound" :key="sound">{{ sound || $t('none') }}</option>
+				<template #text><button class="_textButton" @click="listen(sfxNotification)" v-if="sfxNotification"><fa :icon="faPlay"/> {{ $t('listen') }}</button></template>
+			</mk-select>
+			<mk-select v-model="sfxChat">
+				<template #label>{{ $t('_sfx.chat') }}</template>
+				<option v-for="sound in sounds" :value="sound" :key="sound">{{ sound || $t('none') }}</option>
+				<template #text><button class="_textButton" @click="listen(sfxChat)" v-if="sfxChat"><fa :icon="faPlay"/> {{ $t('listen') }}</button></template>
+			</mk-select>
+			<mk-select v-model="sfxChatBg">
+				<template #label>{{ $t('_sfx.chatBg') }}</template>
+				<option v-for="sound in sounds" :value="sound" :key="sound">{{ sound || $t('none') }}</option>
+				<template #text><button class="_textButton" @click="listen(sfxChatBg)" v-if="sfxChatBg"><fa :icon="faPlay"/> {{ $t('listen') }}</button></template>
+			</mk-select>
+		</div>
+	</section>
+
 	<section class="_card">
 		<div class="_title"><fa :icon="faCog"/> {{ $t('accessibility') }}</div>
 		<div class="_content">
@@ -45,7 +75,7 @@
 
 <script lang="ts">
 import Vue from 'vue';
-import { faImage, faCog } from '@fortawesome/free-solid-svg-icons';
+import { faImage, faCog, faMusic, faPlay } from '@fortawesome/free-solid-svg-icons';
 import MkInput from '../../components/ui/input.vue';
 import MkButton from '../../components/ui/button.vue';
 import MkSwitch from '../../components/ui/switch.vue';
@@ -55,6 +85,17 @@ import XTheme from './theme.vue';
 import i18n from '../../i18n';
 import { langs } from '../../config';
 
+const sounds = [
+	null,
+	'syuilo/pope1',
+	'syuilo/pope2',
+	'syuilo/waon',
+	'aisha/1',
+	'aisha/2',
+	'aisha/3',
+	'noizenecio/kick_gaba',
+];
+
 export default Vue.extend({
 	i18n,
 
@@ -78,7 +119,8 @@ export default Vue.extend({
 			langs,
 			lang: localStorage.getItem('lang'),
 			fontSize: localStorage.getItem('fontSize'),
-			faImage, faCog
+			sounds,
+			faImage, faCog, faMusic, faPlay
 		}
 	},
 
@@ -117,6 +159,31 @@ export default Vue.extend({
 			get() { return this.$store.state.device.useNotificationsPopup; },
 			set(value) { this.$store.commit('device/set', { key: 'useNotificationsPopup', value }); }
 		},
+
+		sfxVolume: {
+			get() { return this.$store.state.device.sfxVolume; },
+			set(value) { this.$store.commit('device/set', { key: 'sfxVolume', value }); }
+		},
+
+		sfxNote: {
+			get() { return this.$store.state.device.sfxNote; },
+			set(value) { this.$store.commit('device/set', { key: 'sfxNote', value }); }
+		},
+
+		sfxNotification: {
+			get() { return this.$store.state.device.sfxNotification; },
+			set(value) { this.$store.commit('device/set', { key: 'sfxNotification', value }); }
+		},
+
+		sfxChat: {
+			get() { return this.$store.state.device.sfxChat; },
+			set(value) { this.$store.commit('device/set', { key: 'sfxChat', value }); }
+		},
+
+		sfxChatBg: {
+			get() { return this.$store.state.device.sfxChatBg; },
+			set(value) { this.$store.commit('device/set', { key: 'sfxChatBg', value }); }
+		},
 	},
 
 	watch: {
@@ -137,6 +204,12 @@ export default Vue.extend({
 	},
 
 	methods: {
+		listen(sound) {
+			const audio = new Audio(`/assets/sounds/${sound}.mp3`);
+			audio.volume = this.$store.state.device.sfxVolume;
+			audio.play();
+		},
+
 		cacheClear() {
 			// Clear cache (service worker)
 			try {
diff --git a/src/client/pages/settings/theme.vue b/src/client/pages/preferences/theme.vue
similarity index 100%
rename from src/client/pages/settings/theme.vue
rename to src/client/pages/preferences/theme.vue
diff --git a/src/client/router.ts b/src/client/router.ts
index 86ef4c7056..3b2bbe9c80 100644
--- a/src/client/router.ts
+++ b/src/client/router.ts
@@ -46,7 +46,7 @@ export const router = new VueRouter({
 		{ path: '/my/groups', component: page('my-groups/index') },
 		{ path: '/my/groups/:group', component: page('my-groups/group') },
 		{ path: '/my/antennas', component: page('my-antennas/index') },
-		{ path: '/settings', component: page('settings/index') },
+		{ path: '/preferences', component: page('preferences/index') },
 		{ path: '/instance', component: page('instance/index') },
 		{ path: '/instance/emojis', component: page('instance/emojis') },
 		{ path: '/instance/users', component: page('instance/users') },
diff --git a/src/client/store.ts b/src/client/store.ts
index 2d84b7b318..4a329a0ebb 100644
--- a/src/client/store.ts
+++ b/src/client/store.ts
@@ -41,6 +41,11 @@ const defaultDeviceSettings = {
 	imageNewTab: false,
 	showFixedPostForm: false,
 	useNotificationsPopup: true,
+	sfxVolume: 0.3,
+	sfxNote: 'syuilo/pope1',
+	sfxNotification: 'syuilo/pope2',
+	sfxChat: 'syuilo/waon',
+	sfxChatBg: null,
 	userData: {},
 };